【发布时间】:2011-03-07 07:45:35
【问题描述】:
我想创建一个 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”。但相反,我只看到一个空白窗口。所以很明显我错过了一些东西。
我怎样才能修复上面的代码,以便“子”控件在运行时出现,但不会暴露给其他人乱七八糟(不能避免)?
【问题讨论】:
标签: wpf encapsulation frameworkelement dynamic-ui