0

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

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

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

  2. 内部 Grid 结构是动态的,有许多/未知的内容,但每种内容都是静态的,可以用单独的 XAML 表示。所以我会有 InnerGrid_1.xaml、InnerGrid_2.xaml、InnerGrid_n.xaml 等。

  3. 在运行时,取决于 ListBox 选择,应显示某些 InnerGrid。

我正在考虑两种方法来做到这一点:

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

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

我知道第一种方法可行,但需要在代码中进行复杂的 XML 操作(或文本编辑)。我想要第二种方式,但不确定它是否可行。特别是,我可能会更改 TopGrid 中单元格的大小以容纳动态 InnerGrid。

有人做过这个并且可以阐明一些吗?或任何更好的解决方案?

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

4

1 回答 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。您应该研究数据模板。

于 2013-01-17T12:17:07.887 回答