在运行时动态创建(封装)儿童的WPF元素
-
29-09-2019 - |
题
我想创建一个WPF元素,该元素在运行时完全控制其子元素 - 当其属性更改时添加和删除子UI。当您修改其物品属性属性时,有点像ItemScontrol会做什么,尽管在我的情况下只有一个孩子。
这将是MVVM的视图容器 - 当您给它一个模型或视图模型时,它将神奇地创建正确的视图并将所有内容连接起来。我的视图容器不需要模板(因为它创建用户定义的视图,它们是UserControls,并且具有自己的模板),我希望它尽可能地封装。我可能可以通过从网格之类的东西中降下来轻松地做到这一点,并在我自己的属性发生变化时添加子控制;但是网格公开公开其子元素的收集,并允许任何人添加和删除东西。
我应该从哪个WPF类中下降以进行最大封装,以及如何在运行时添加子元素?
根据我对文档的理解,我尝试使用Frameworkelement和AddVisualChild,只是为了看看是否可以在运行时创建子控制器。我尚不清楚是否需要AddLogicalChild,但我以防万一:
public class ViewContainer : FrameworkElement {
private TextBlock _child;
public ViewContainer() {
_child = new TextBlock { Text = "ViewContainer" };
AddLogicalChild(_child);
AddVisualChild(_child);
InvalidateMeasure();
}
public object Content { get; set; }
protected override Size ArrangeOverride(Size finalSize) {
_child.Arrange(new Rect(finalSize));
return finalSize;
}
protected override Size MeasureOverride(Size availableSize) {
_child.Measure(availableSize);
return _child.DesiredSize;
}
}
当我将ViewContainer放入窗口并运行此时,我希望看到一个文字屏幕上的“ ViewContainer”。但是,我只是看到一个空白窗口。所以显然我缺少一些东西。
如何修复上述代码,以便在运行时出现“孩子”控件,但不会暴露于其他人(比避免的更多)?
解决方案
要回答您的特定问题,您还需要覆盖 getVisualChild 和 VisualChildRencount 属性使您的子元素能够显示。
其他提示
您是否考虑过利用WPF对隐式数据模拟的支持?
我处理与您类似的要求的方式是使用 ContentControl
. 。我约束 Content
属性到我的ViewModel。然后,我确保在ContentControl上方的某个地方引用的资源词典中,我已为所有可能分配给内容属性的视图模型定义的数据档案。
这样,WPF会考虑到我的ViewModel的正确视图。