WPF&Silverlight之XamlReader動態創建控件並綁定


使用 XamlReader.Load

XamlReader 是一個很大程度上具有方法的無狀態的靜態類,它可基於輸入的 XAML 標記創建對象。XamlReader 提供並行如何通過 Silverlight 運行時和 Silverlight 應用程序模型對 XAML 進行分析的對象構建行為。 分析 XAML 生成托管對象的運行時對象樹。 該對象樹提供方法以便對那些在運行時使用命名的引用(由分析的 XAML中的 Name 或 x:Name 標識)或正經過完整樹的部分的那些對象進行編程。

當使用 Load 方法創建 XAML 對象時,有幾個要重點理解的一般概念。

XAML 內容字符串必須定義單個根元素。

XAML 內容字符串必須是格式良好的 XML,並且必須是有效的 XAML。

根元素必須聲明在 XAML 中引用的任何實體所需的 XAML 命名空間。 對於默認的 Silverlight XAML 命名空間這是真實的,Load 的大多數字符串應指定根元素中的 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ,以便 Silverlight 核心 XAML 命名空間是默認的 XAML 命名空間。

XAML 命名空間映射中引用的任何自定義程序集必須已可用於應用程序,(通常通過 AssemblyPart 包裝)。

Load 的 XAML 不應嘗試指定 x:Class,或包括事件處理程序的任何 XAML 定義的屬性。 Load 邏輯不能集成具有運行時代碼隱藏類的加載的 XAML。 如果您要添加事件處理程序,則必須在代碼中這樣做:引用 Load 結果的對象樹結構內獲得的對象,並將特定於語言的語法用於附加處理程序(如 += )。 有關使用代碼的附加事件的更多信息,請參見 Silverlight 的事件概述。

將創建的對象樹與主 Silverlight 對象樹連接 下圖演示了 Silverlight 對象層次結構和從 XAML 片段新創建的對象樹之間的關系。

斷開連接的 Silverlight 對象樹

瀏覽器托管的 HTML 頁面中的所有 Silverlight 內容最后才呈現,原因是,在對象關系中,它與 Silverlight 應用程序模型中加載為 RootVisual 的對象連接。 然后,RootVisual 是復合的 Silverlight,並且,將呈現相應的內容並傳遞到使用一種插件/控制訪問層( Silverlight 實現在其本機代碼的)的 HTML 主機。 最初,不呈現任何沒有連接至主對象樹(基於 RootVisual 的樹)的對象樹。

當您在 XAML 片段中創建了一個斷開連接的對象樹時,可以通過調用存在於主要對象樹中的 Api 對象將其添加到主 Silverlight 對象樹。 可以將斷開連接的對象樹設置為現有對象的屬性值,也可以作為子對象將將其添加到其它對等對象的集合中。 (后者實際上也是屬性設置,只不過您設置的是父對象的屬性的集合。)當該片段成為主要的 Silverlight 對象樹的一部分時,Silverlight 將檢查由主對象樹所組成的更改,並呈現 XAML 片段中的對象。 下圖演示了 Silverlight 對象樹和來自分析 XAML 片段的對象樹之間新的關系(連接后)。

已連接的 Silverlight 對象樹

對於將 XAML 生成的內容動態添加到主 Silverlight 對象樹,有以下一些要求:

必須存在與 Silverlight 插件關聯的 XAML 內容,不能替換整個內容樹。 必須至少保留原始根元素。

在 XAML 分析 API 中創建的對象只能將能分配給主對象中的一個對象。 (這與初始 XAML 處理行為相似,即 XAML 與所創建的對象之間是 1:1 的關系,模板的特殊情況除外。)如果希望將向不同區域的應用程序主對象樹添加同一 XAML 創建的對象,則必須使用同一輸入字符串和不同的返回值目標多次分析 XAML。

期望用作連接點的主對象樹中現有的 Silverlight 對象必須支持適當的屬性至集。 換句話說,連接點對象必須有某種形式的可設置的屬性值。 一些示例如下:

連接點對象支持諸如 Child 或 Content 這樣的廣義的子元素屬性,這需要一個基類型,如 UIElement。 新對象樹的根對象必須可分配給該屬性。

連接點對象支持集合屬性,並且該屬性的集合類型也支持 Add 方法。 新對象樹然后可以作為一個項目添加。

連接點對象支持特定類型的屬性值相匹配的新樹的根對象。 例如,您可以創建一個新的 Brush 與 Load 輸入,然后使用它來設置 Background 值。

從 XAML 創建對象的安全問題 為了使基於 Silverlight 的應用程序免受安全攻擊,強烈建議您不要將不可信的 XAML 字符串傳遞給 Load(或傳遞給 JavaScript equivalent CreateFromXaml)。 不可信的 XAML 可能包含鏡像合法站點的偽裝接口,這將導致欺騙安全威脅。 此外,XAML 可能包含對腳本事件處理程序的引用。如果您還未准備好通過指定當前加載的 XAML 的 x:Class 聲明 XAML 中的托管 API,這需要尤為注意:默認的不含 x:Class 的編程模型為 JavaScript。 其結果是將向主樹添加不受信任的 XAML 可能會導致無意執行腳本的 Silverlight 應用程序對象樹。 應始終確認使用的 XAML 內容的來源是可信的。

動態加載並綁定實例

StringBuilder sb = new StringBuilder();            

sb.Append(@"<Paragraph xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">XXXXXX");            

sb.Append(@"<Run Foreground=""Red"" FontWeight=""Normal"" Text=""{Binding Filed,Mode=OneWay}""></Run> XXXXXX");            

sb.Append(@"</Paragraph>");            

Paragraph pg = (Paragraph)XamlReader.Load(sb.ToString());            

if ((Paragraph)txtTopInfo.Blocks[0] != pg)            

{             

    txtTopInfo.Blocks.Clear();             

    this.txtTopInfo.Blocks.Add(pg);            

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM