我想创建一个 WPF 元素,该元素在运行时完全控制其子元素——在其属性更改时添加和删除子 UI。有点像 ItemsControl 在您修改 ItemsSource 属性时所做的事情,尽管在我的情况下只有一个孩子。
这将是 MVVM 的视图容器——当你给它一个模型或视图模型时,它会神奇地创建正确的视图并将所有内容连接起来。我的视图容器不需要模板化(因为它创建了用户定义的视图,这些视图是 UserControls 并且有自己的模板),我希望它尽可能地封装。我可以很容易地做到这一点,方法是从像 Grid 这样的东西下降,并在我自己的属性发生变化时添加子控件;但是 Grid 公开了它的子元素集合,并允许任何人添加和删除东西。
为了最大程度的封装,我应该从哪个 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 放入 Window 并运行它时,我希望看到一个 TextBlock 说“ViewContainer”。但相反,我只看到一个空白窗口。所以很明显我错过了一些东西。
如何修复上面的代码,以便“子”控件确实在运行时出现,但不会暴露给其他人乱搞(不能避免)?