首页 文章

WPF:在运行时用子XAML替换Visual Tree的分支?

提问于
浏览
0

为了简化问题,我将描述一个简化的用例:

假设我有一个包含1个动态内部网格的顶级网格和一个适合顶级网格的某些单元格的ListBox:

  • 顶级网格结构(TopGrid.xaml)是相对静态的,只包含内部网格的单元格的动态大小 .

  • 内部网格结构是动态的,有许多/未知类型的内容,但每种内容都是静态的,可以用单独的XAML表示 . 所以我将有InnerGrid_1.xaml,InnerGrid_2.xaml,InnerGrid_n.xaml等 .

  • 在运行时,依赖于ListBox选择,应显示某些InnerGrid .

我正在考虑两种方法:

  • 运行时文本编辑代码中的XAML:在代码中,使用XmlDocument编辑TopGrid.xaml以添加某些InnerGrid_x.xaml的内容以创建最终的内存中TopGrid.xaml . 然后使用XamlReader将最终的TopGrid.xaml读入Visual Tree,然后将树添加到LayoutRoot以显示它 .

  • 可视树操作(无文本编辑):在代码中,使用XamlReader将TopGrid.xaml读入顶部可视树,将InnerGrid_x.xaml读入子可视树 . 然后使用VisualTreeHelper在top-visual-tree中查找TopGrid元素,在子视觉树中找到InnerGrid元素 . 然后将子视觉树添加到顶部可视树 . 然后将组合树添加到LayoutRoot中显示它 .

我知道第一种方法可行,但需要在代码中进行复杂的XML操作(或文本编辑) . 我希望第二种方式,但不确定它是否会起作用 . 特别是,我可能会改变TopGrid中单元格的大小来保存动态InnerGrid .

有人这样做了,可以解决一些问题吗?还是更好的解决方案?

一个附带问题:似乎动态加载的XAML无法在XAML(我的测试)中指定事件处理程序,我需要在创建树后动态设置事件处理程序 . 真的吗?

1 回答

  • 1

    WPF的方式是绑定到您的数据,让WPF解析可视化树:

    <Grid>
        ...
        <ContentControl Content="{Binding SomeData}"/>
    

    为了呈现您的内容,WPF将查找匹配数据类型的 DataTemplate . 因此,对于您拥有的每种类型的数据,您将定义 DataTemplate

    <DataTemplate DataType="...">
        <!-- your visual tree representing the data goes here -->
    </DataTemplate>
    

    您还可以通过指定 ContentTemplate 属性明确告诉WPF如何表示您的数据:

    <ContentControl Content="{Binding SomeData}" ContentTemplate="{StaticResource MyContentTemplate}"/>
    

    TLDR:您提出的方法都不是惯用的WPF . 您应该查看数据模板 .

相关问题