Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在运行时动态创建(封装)子级的WPF元素_Wpf_Encapsulation_Frameworkelement_Dynamic Ui - Fatal编程技术网

在运行时动态创建(封装)子级的WPF元素

在运行时动态创建(封装)子级的WPF元素,wpf,encapsulation,frameworkelement,dynamic-ui,Wpf,Encapsulation,Frameworkelement,Dynamic Ui,我想创建一个WPF元素,该元素在运行时完全控制其子元素——在其属性更改时添加和删除子UI。有点像ItemsControl在修改其ItemsSource属性时所做的操作,不过在我的例子中只有一个子项 这将是一个MVVM的视图容器——当您给它一个模型或ViewModel时,它将神奇地创建正确的视图并连接所有内容。我的视图容器不需要是可模板化的(因为它创建了用户定义的视图,这些视图是用户控件,并且有自己的模板),我更希望它尽可能地进行封装。我可以很容易地做到这一点,当我自己的属性发生变化时,我可以从类

我想创建一个WPF元素,该元素在运行时完全控制其子元素——在其属性更改时添加和删除子UI。有点像ItemsControl在修改其ItemsSource属性时所做的操作,不过在我的例子中只有一个子项

这将是一个MVVM的视图容器——当您给它一个模型或ViewModel时,它将神奇地创建正确的视图并连接所有内容。我的视图容器不需要是可模板化的(因为它创建了用户定义的视图,这些视图是用户控件,并且有自己的模板),我更希望它尽可能地进行封装。我可以很容易地做到这一点,当我自己的属性发生变化时,我可以从类似网格的地方降下来,并添加子控件;但网格公开了它的子元素集合,并允许任何人添加和删除内容

为了最大限度地封装,我应该从哪个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”。但是相反,我只看到一个空白的窗口。所以很明显我错过了什么


我如何修复上面的代码,使“child”控件在运行时出现,但不会被其他人弄乱(这是可以避免的)

您是否考虑过利用WPF对隐式数据模板的支持

我处理类似于您的需求的方法是使用
ContentControl
。我将
内容
属性绑定到我的ViewModel。然后,我确保在ContentControl上方的树中引用的资源字典中,为可能分配给Content属性的所有类型的ViewModels定义了DataTemplates


通过这种方式,WPF负责为我的ViewModel连接正确的视图。

要回答您的特定问题,您还需要重写和属性以使子元素能够显示。

是的,我以前已经这样做过,但这次我想更进一步——我希望我的ViewContainer能够获取一个模型,并自动发现并为其创建正确的ViewModel,然后从那里转到视图。我不认为DataTemplate.DataType会在没有帮助的情况下把我带到那里。当然,DataTemplate.DataType不适合,但是DataTemplateSelector可能会。很酷——就是这样。虽然我有点困惑,为什么会有一个AddVisualChild,如果它实际上没有添加到任何东西中。啊,我明白了。它使孩子了解自己的父母;但许多家长不需要孩子的列表(没有孩子或只有一个孩子),因此存储的选择和责任由家长决定。积极的关注点分离:我非常喜欢WPF的一个方面。但这意味着“AddVisualChild”这个名字有误导性,因为它表明它正在将它添加到某种列表中,而事实并非如此。