1

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

4

2 回答 2

8

要看。

我认为您的主要问题是 aContentPresenter仅在控件模板中使用。您不能只是将其粘贴在 Window 中并期望它显示窗口的内容。我相信您真正需要做的是使用ContentControl来托管您的 UI。

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

首先,对于每个视图,创建一个模型(或 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. 搜索资源的默认DataTemplateSelector设置为ContentControlDataTemplateDataTypetypeof(Dialog)
  5. 它在窗口的资源中找到这个 DataTemplate
  6. DataTemplate 的内容被加载并添加为ContentControl

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

使用 MVVM,您可以将 ViewModel 的属性绑定到该Content属性(称为 Current 或其他名称),然后根据 ViewModel 的当前状态将属性中的模型切换为预期值。请注意,在 ContentControl 中,对Content属性设置的任何内容都将成为DataContextContentControl 的直接子项的 。类似于ItemsSourceanItemsControl中的DataContexteach是ItemTemplate.

于 2012-12-10T18:39:56.453 回答
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();
于 2012-12-10T19:28:14.387 回答