WPF 级联绑定

WPF Cascading Binding

主题:如何防止 UserControl 上的绑定覆盖使用此 UserControl 的上层(主要)Window 给出的绑定。

我已经阅读了有关该主题的帖子和一些书籍,但我仍然对绑定机制感到困惑。 即使在一些专业书籍中也几乎没有提到 DependencyPropertyAttachedProperty 的术语。 Microsoft 文档很好,但有些简陋。

此示例是 Head First C# 的 BasketballRoster MVVM 示例的极端简化

我有一个 usercontrol,一个简单的 circle

...  
xmlns:vm_nmspc="clr-namespace:BindingMCVE.ViewModel" >
             
<UserControl.Resources>
    <vm_nmspc:my_usercontrol_vm x:Key="MyUserControlVM"/>
</UserControl.Resources>

<Grid>
    <StackPanel  DataContext="{DynamicResource ResourceKey=MyUserControlVM}" Height="100"  Width="100">
        <Ellipse Fill="{Binding my_color}" Height="50" Width="50"/>
    </StackPanel>
</Grid>

我喜欢的是提供一个无参数构造函数 my_usercontrol_vm() 这样我就可以查看我的圈子在我处理 UserControl 的视图时充满红色

为此,我在 UserControlResources 中使用了 class my_usercontrol_vm 的实例。 这里我使用了 DynamicResource 关键字(我首先测试了 StaticResource )

class my_usercontrol_vm
{
    public string my_color {get; set;}

    public my_usercontrol_vm() : this("Red") { }

    public my_usercontrol_vm(string color)
    {
        my_color = color;
    }
}

现在我想在一个 (Main)Window 中使用几个 UserControl,仍然 使用绑定 “实时”[=] 中查看74=] 我的观点的演变。

xmlns:vm_nmspc="clr-namespace:BindingMCVE.ViewModel" >

<Window.Resources>
    <vm_nmspc:main_window_vm x:Key="MainWindowVM"/>   
</Window.Resources>

<Grid>
    <StackPanel DataContext="{DynamicResource ResourceKey=MainWindowVM}">
        
        <view_nmspc:UserControl1 DataContext="{Binding usr_ctrl_1}"/>
        <view_nmspc:UserControl1 DataContext="{Binding usr_ctrl_2}"/>
        
    </StackPanel>
</Grid>
</Window>

ViewModel class 专用于 MainWindow

class main_window_vm
{
    public my_usercontrol_vm usr_ctrl_1 { get; set; }
    public my_usercontrol_vm usr_ctrl_2 { get; set; }

    public main_window_vm()
    {
        usr_ctrl_1 = new my_usercontrol_vm("Green");
        usr_ctrl_2 = new my_usercontrol_vm("Blue");
    }
}

请注意,我期待看到绿色蓝色实心圆圈。

然而我得到的是红色

我会得到绿色和蓝色的圆圈我没有在 UserControl 中放置资源

在使用调试器时,我可以看到我首先进入 class main_window_vm 的构造函数,之后(2 次) classmy_user_control_vm,这样两个圆圈最后都是红色的。

我知道目前我对 WPF 的了解可能只有 10%,但我认为这种做法是非常正确的。最后,我请求在 MainWindow 中 UserControl1 控件 绑定 到 属性 usr_ctrl_X 的 class main_window_vm

欢迎任何建议。

此致。

NGI

您正在设置 UserControlDataContext,但是 Ellipse 没有使用它,因为它继承了 StackPanelDataContext ].这不会改变,并且将始终绑定到您的 MyUserControlVM 资源。

您应该从 StackPanel 中删除 DataContext="{DynamicResource ResourceKey=MyUserControlVM}"。如果您将此添加到 UserControl,那么您的绑定应该会覆盖它。您还可以使用混合设计命名空间来设置仅在设计时使用的设计 DataContext

根据 Charles Mager 的回答(非常感谢),我 post 对我自己的问题进行了回复,以便每个人都有答案。

所以查尔斯建议将 DataContext 放入 UserControl 而不是 StackPanel

<UserControl x:Class="BindingMCVE.UserControl1"
    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" 
    d:DesignHeight="100" d:DesignWidth="100"
    xmlns:vm_nmspc="clr-namespace:BindingMCVE.ViewModel"             
    DataContext="{DynamicResource ResourceKey=MyUserControlVM}"  >
    <!--DataContext added above-->

    <UserControl.Resources>
        <vm_nmspc:my_usercontrol_vm x:Key="MyUserControlVM"/>
    </UserControl.Resources>

<Grid>
    <!--DataContext removed from StackPanel below-->
    <StackPanel  Height="100"  Width="100">
        <Ellipse  Fill="{Binding my_color}" Height="50" Width="50"/>
    </StackPanel>
</Grid>
</UserControl>

这里是: