如何将 UserControl 加载到 (WPF) 窗口内的 ContentPresenter 中? [英] How do I load a UserControl into a ContentPresenter within a (WPF) Window?
问题描述
我有一个包含 Viewbox 的窗口.在那个 Viewbox 中,我想拥有我已经创建为 UserControls 的几个视图之一.我正在使用 MVVM(模型视图视图模型)设计模式.我在网上搜索了大约一个小时,但找不到任何解释如何使用 ContentPresenter
显示 UserControl 的示例或教程.
取决于.
我认为您的主要问题是 ContentPresenter
仅在控件模板中使用.你不能只是把它贴在一个窗口中并期望它显示窗口的内容.我相信您真正需要做的是使用ContentControl 来托管您的 UI.
通过将您的模型绑定到该控件的 Content
属性,您可以设置包含该模型的预期视图的 DataTemplates.我给你一个简短的例子.请注意,这可能与您的设计不符,但它展示了这一切是如何结合在一起的.
首先,为每个视图创建一个模型(或 ViewModel)来管理该视图的数据(和交互).
public 密封类 Dialog : INotifyPropertyChanged//或 DependencyObject{public string Input {get;set;}//INPC 或 DP 实现未显示公共 ICommand 取消 {get;set;}//类定义未显示}
接下来,定义要在 ContentPresenter 中显示的视图
<Border BorderBrush="红色" BorderThickness="5"><TextBlock Text="{绑定输入}"/><Button Command="{绑定取消}">取消</Button><!-- 等等等等--></边框></用户控件>
接下来,在您的窗口中,添加 ContentControl 和 DataTemplate
<窗口.资源><DataTemplate xmlns:t="clr-namespace:Herp"DataType="{x:Type t:Dialog}"><t:DialogView/></DataTempalte></Window.Resources><ContentControl Content="{Binding}"/></窗口>
最后将窗口的 DataContext 设置为您的 Dialog
模型.
public MyWindow(){初始化组件();DataContext = new Dialog();}
逻辑流程如下:
- 您的窗口已创建.
- 在 DataContext 上设置了一个 Dialog 控件实例.
- 更新了 ContentControl 上的绑定
- DataTemplateSelector 的默认DataTemplateSelectorcode>ContentControl 在资源中搜索
DataTemplate
的DataType
设置为typeof(Dialog)
- 它在窗口的资源中找到这个 DataTemplate
- DataTemplate 的内容被加载 并添加为
ContentControl
的可视子项
任何时候 ContentControl
的 Content
发生变化,相同的过程都会重复.因此,您可以拥有许多不同的模型,每个模型都有包含不同 UserControl 的不同 DataTemplate,并且每次更新 ContentControl 上的绑定时,您都会看到预期的视图.
使用 MVVM,您可以将 ViewModel 的属性绑定到 Content
属性(称为 Current 或其他名称),然后根据 ViewModel 的当前值将属性中的模型切换为预期值状态.请注意,在 ContentControl 中,设置为 Content
属性的任何内容都将成为 ContentControl 的直接子级的 DataContext
.类似于 ItemsControl
中的每个 ItemsSource
是 ItemTemplate
中定义的可视化树的 DataContext
.>
I have a window that contains a Viewbox. In that Viewbox, I would like to have one of several views which I have already created as UserControls. I am using the MVVM (Model View View-Model) design pattern. I have searched for about an hour online, and I cannot find any examples or tutorials that explain how to display a UserControl using a ContentPresenter
.
Depends.
I think your main issue is that a ContentPresenter
is only used within a control template. You can't just stick it in a Window and expect it to show the content of the window. I believe what you really need to do is to use a ContentControl to host your UI.
By binding your model to the Content
property of this control, you can set up DataTemplates that contain the expected view for that model. I'll give you an abbreviated example. Note, this may not match your design, but it demonstrates how it all goes together.
First, for each view, create a Model (or ViewModel) which manages the data (and interaction) for that view.
public sealed class Dialog : INotifyPropertyChanged // or DependencyObject
{
public string Input {get;set;} // INPC or DP implementation not shown
public ICommand Cancel {get;set;}
// class definition not shown
}
Next, define your View to be shown in the ContentPresenter
<UserControl x:Class="Herp.DialogView"
HideImplementationDetails="true">
<Border BorderBrush="Red" BorderThickness="5">
<TextBlock Text="{Binding Input}" />
<Button Command="{Binding Cancel}">Cancel</Button>
<!-- etc etc -->
</Border>
</UserControl>
Next, in your window, add the ContentControl and the DataTemplate
<Window HideImplementationDetailsForBrevityOfXaml="true">
<Window.Resources>
<DataTemplate xmlns:t="clr-namespace:Herp"
DataType="{x:Type t:Dialog}">
<t:DialogView />
</DataTempalte>
</Window.Resources>
<ContentControl Content="{Binding}" />
</Window>
And finally set the DataContext of the Window to your Dialog
model.
public MyWindow()
{
InitializeComponent();
DataContext = new Dialog();
}
This is how the logic flows:
- Your window is created.
- An instance of the Dialog control is set on the DataContext.
- The binding on the ContentControl is updated
- The default DataTemplateSelector of the
ContentControl
searches resources for aDataTemplate
whoseDataType
is set totypeof(Dialog)
- It finds this DataTemplate within the Window's Resources
- The content of the DataTemplate is loaded and added as a visual child of the
ContentControl
Any time the Content
of the ContentControl
changes, the same process repeats. So you can have many different models, each with a different DataTemplate containing a different UserControl, and every time you update the binding on the ContentControl you see the expected View.
With MVVM, you would bind a property of your ViewModel to the Content
property (call it Current or something), then switch out the model within the property to the expected value depending on the ViewModel's current state. Note, within a ContentControl, whatever is set to the Content
property becomes the DataContext
of the immediate child of the ContentControl. Similar to how each ItemsSource
within an ItemsControl
is the DataContext
of the visual tree defined within the ItemTemplate
.
这篇关于如何将 UserControl 加载到 (WPF) 窗口内的 ContentPresenter 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!