如何将 UserControl 加载到 (WPF) 窗口内的 ContentPresenter 中? [英] How do I load a UserControl into a ContentPresenter within a (WPF) Window?

查看:103
本文介绍了如何将 UserControl 加载到 (WPF) 窗口内的 ContentPresenter 中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 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();}

逻辑流程如下:

  1. 您的窗口已创建.
  2. 在 DataContext 上设置了一个 Dialog 控件实例.
  3. 更新了 ContentControl 上的绑定
  4. DataTemplateSelector 的默认DataTemplateSelectorcode>ContentControl 在资源中搜索 DataTemplateDataType 设置为 typeof(Dialog)
  5. 它在窗口的资源中找到这个 DataTemplate
  6. DataTemplate 的内容被加载 并添加为 ContentControl
  7. 的可视子项

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

使用 MVVM,您可以将 ViewModel 的属性绑定到 Content 属性(称为 Current 或其他名称),然后根据 ViewModel 的当前值将属性中的模型切换为预期值状态.请注意,在 ContentControl 中,设置为 Content 属性的任何内容都将成为 ContentControl 的直接子级的 DataContext.类似于 ItemsControl 中的每个 ItemsSourceItemTemplate 中定义的可视化树的 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:

  1. Your window is created.
  2. An instance of the Dialog control is set on the DataContext.
  3. The binding on the ContentControl is updated
  4. The default DataTemplateSelector of the ContentControl searches resources for a DataTemplate whose DataType is set to typeof(Dialog)
  5. It finds this DataTemplate within the Window's Resources
  6. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆