如何将UserControl加载到(WPF)窗口中的ContentPresenter中?

时间:2012-12-10 17:58:32

标签: wpf mvvm user-controls contentpresenter

我有一个包含Viewbox的窗口。在那个Viewbox中,我想拥有一些我已经创建为UserControls的视图。我正在使用MVVM(模型视图 - 模型)设计模式。我在线搜索了大约一个小时,我找不到任何解释如何使用ContentPresenter显示UserControl的示例或教程。

2 个答案:

答案 0 :(得分:8)

取决于

我认为您的主要问题是ContentPresenter仅在控件模板中使用。你不能只是把它粘在一个窗口中,并期望它显示窗口的内容。我相信您真正需要做的就是使用ContentControl来托管您的用户界面。

通过将模型绑定到此控件的Content属性,可以设置包含该模型的预期视图的DataTemplates。我会给你一个简短的例子。请注意,这可能与您的设计不符,但它会演示如何将它们组合在一起。

首先,为每个视图创建一个Model(或ViewModel),用于管理该视图的数据(和交互)。

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
}

接下来,定义要在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>

接下来,在您的窗口中,添加ContentControl和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>

最后将Window的DataContext设置为Dialog模型。

public MyWindow()
{
    InitializeComponent();
    DataContext = new Dialog();
}

这就是逻辑流程:

  1. 您的窗口已创建。
  2. 在DataContext上设置Dialog控件的实例。
  3. ContentControl上的绑定已更新
  4. ContentControl DataTemplate的默认DataTemplateSelector搜索DataType typeof(Dialog)设为ContentControl
  5. Content资源
  6. 它在Window的资源
  7. 中找到了这个DataTemplate
  8. DataTemplate的内容为loaded,并作为ContentControl
  9. 的视觉子项添加

    Content的{​​{1}}发生变化时,重复相同的过程。因此,您可以拥有许多不同的模型,每个模型都有一个包含不同UserControl的不同DataTemplate,每次更新ContentControl上的绑定时,您都会看到预期的视图。

    使用MVVM,您可以将ViewModel的属性绑定到Content属性(称为Current或其他),然后根据ViewModel的当前状态将属性中的模型切换为期望值。请注意,在ContentControl中,设置为DataContext属性的任何内容都将成为ContentControl的直接子项的ItemsSource。类似于ItemsControl中的每个DataContextItemTemplate中定义的可视树的{{1}}类似。

答案 1 :(得分:1)

我在这里隐藏了很多关于OK和Cancel的view-viewmodel交互的细节,但是只要你设置了DataTemplate,那么这应该在窗口内呈现你的视图。

我的应用程序资源字典中定义了viewmodel-view数据窗口:

<DataTemplate DataType="{x:Type SaveDocumentChangesVM}">
    <SaveDocumentChangesView />
</DataTemplate>

托管视图的窗口:

<Window x:Class="CustomDialogWindow" 
        SizeToContent="WidthAndHeight" ShowInTaskbar="False">
    <ContentPresenter Name="DialogContentPresenter" />
</Window>

窗口的构造函数:

public CustomDialogWindow(object viewModel, string dialogTitle)
{
    InitializeComponent();

    // A datatemplate will allow WPF to figure out how to render the window contents
    DialogContentPresenter.Content = viewModel;

    if (dialogTitle != null)
    {
        Title = dialogTitle;
    }
}

显示如下对话框:

var vm = new SaveDocumentChangesVM();
var dialog = new CustomDialogWindow(vm, "This is my dialog");
dialog.ShowDialog();