wpf - 在WPF Blend的逻辑树中设置DataContext

标签 wpf xaml mvvm datacontext

我对窗口的数据上下文及其子控件如何继承有疑问。

如果我有一个Window,在XAML中将其DataContext属性设置为:

<Window.DataContext>
    <local:SomeViewModel />
</Window.DataContext>

通过将用户控件添加到窗口中,我知道该用户控件将从窗口继承其数据上下文(除非我另外指定)。
<local:MyUserControl />

在用户控件内该如何处理?由于它是不同的XAML文件,如何在用户控件中强烈键入数据上下文?因此,如果我在控件中指定数据上下文:
<UserControl.DataContext>
    <local:SomeViewModel />
</UserControl.DataContext>

这会否覆盖Window的 View 模型实例,从而在内存中创建一个新实例?我认为是的,如果是这样,如何通过xaml将 View 模型传递给 subview ?我知道我可以在代码后面通过直接分配来做到这一点,但我希望这可以在xaml中进行处理。

我们已经隔离了大部分的UI,目前必须在后面的代码中手动分配上下文。

我尝试使用RelativeSource,但似乎没有用。也许我用错了,但是上下文从未消失。

有什么想法吗?

更新1

为了澄清,我展示了一个简单的Window,其中DataContext设置为自定义 View 模型。
<Window x:Class="MyProject.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModels="clr-namespace:MyProject.ViewModels"
        xmlns:views="clr-namespace:MyProject.MyCustomView">

    <Window.DataContext>
        <viewModels:ProjectViewModel />
    </Window.DataContext>

    <StackPanel>
        <views:MyCustomView />
    </StackPanel>
<Window>

现在,在我的MyCustomView用户控件中,使用该控件的其他开发人员将不知道数据上下文的类型是什么,而无需手动遍历所有可能的父窗口以查看其使用位置。我想在UserControl中执行以下操作:
<UserControl x:Class="MyProject.Views.DiaryDetailsDescription"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" >

<UserControl.DataContext Type="viewModels:ProjectViewModel />

</UserControl>

这样,使用该用户控件的设计人员/开发人员便知道该用户控件的数据上下文将是ProjectViewModel类型,并由拥有的Window继承。

更新2

因此,为了进一步澄清,我想在用户控件XAML中执行的操作等效于以下C#代码。
return (SingleViewModel)this.DataContext;

因此,Blend中的Designer确切知道DataContext的类型。对他来说,DataContext只是用户控件中的一个对象,即使它从Window继承了SingleViewModel上下文。

最佳答案

也许您应该尝试使用一堆DataTemplate + UserControl?在资源中在Window中,使用UserControl创建DataTemplate:

<Window.Resources>
    <DataTemplate DataType="{x:Type vm:SingleViewModel}">
        <vw:SingleView /> <!-- Your UserControl -->
    </DataTemplate>
</Window.Resources>

然后在根面板中添加ContentControl,如下所示:
<ContentControl Name="MyContent"  
                Content="{Binding Path=CurrentViewModel}" />

其中CurrentViewModel可以是SingleViewModel类型。

在这种情况下,我们立即看到使用SingleView类型的vm:SingleViewModel DataContext。有关更多信息,请参见 this this

Edit: more suitable option

您也可以尝试使用 d:DesignInstance :

Use d:DesignInstance for create data bindings at design time for a DataContext that is assigned at run time. To create the data binding, you use the data binding builder to create a special design-time data context and set the DesignInstance to a business object type. DesignInstance is a design-time property.



它已在Blend中成功用于分配DataContext。 d:DesignInstance提供了一种创建非虚假类型的技术,可以在d:DesignInstance上将IsDesignTimeCreatable属性设置为True来启用此功能。

有关更多信息,请参见:

d:DesignInstance, d:DesignData in Visual Studio 2010 Beta2

关于wpf - 在WPF Blend的逻辑树中设置DataContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22777132/

相关文章:

c# - 从窗口句柄获取窗口实例

c# - 访问后更改项目的背景颜色

c# - 当用户在文本框中输入字符时通知 ViewModel

silverlight - 如果支持 VM 的 props 的每个字段都实现 INotifyPropChange,VM 是否需要实现 INotifyPropChagned?

c# - WPF:Initialized 和 Loaded 事件之间是什么?

c# - XAML 中用于绑定(bind)到 ISubject<string> 的标记扩展

XAML,将 Width 和 Height 属性绑定(bind)到其他控件的相同属性

c# - 使用两个图像创建按钮样式

wpf - 扩展器为ListBoxItem不会触发选择

WPF 分层 ViewModel FindAncestor 数据绑定(bind)错误