C# 如何绑定子级“UserControl”';使用“Style”将的依赖项属性转换为宿主元素的属性';s视图模型?

C# 如何绑定子级“UserControl”';使用“Style”将的依赖项属性转换为宿主元素的属性';s视图模型?,c#,wpf,xaml,data-binding,wpf-style,C#,Wpf,Xaml,Data Binding,Wpf Style,如何使用Style将子UserControl的依赖项属性绑定到宿主元素视图模型的属性 我尝试了下面的代码,MyBlock.BlockIsOnlyOne应该通过Style的Setter绑定到视图模型的属性-MyContainerViewModel.ViewModelIsOnlyOne。但由于某种原因,它根本不起作用,MyBlock.BlockIsOnlyOne的值从未改变,尽管MyContainerViewModel.ViewModelIsOnlyOne改变了 容器XAML: <UserCo

如何使用
Style
将子
UserControl
的依赖项属性绑定到宿主元素视图模型的属性

我尝试了下面的代码,
MyBlock.BlockIsOnlyOne
应该通过
Style
Setter
绑定到视图模型的属性-
MyContainerViewModel.ViewModelIsOnlyOne
。但由于某种原因,它根本不起作用,
MyBlock.BlockIsOnlyOne
的值从未改变,尽管
MyContainerViewModel.ViewModelIsOnlyOne
改变了

容器XAML:

<UserControl x:Class="MyNs.MyContainer"
             ...
             >
    <UserControl.DataContext>
        <vc:MyContainerViewModel x:Name="TheDataContext"/>
    </UserControl.DataContext>

    <Grid>
        <Grid.Resources>
            <Style TargetType="{x:Type vc:MyBlock}">
                <Setter Property="BlockIsOnlyOne" Value="{Binding ViewModelIsOnlyOne}"/>
                <!-- Tried this too, with no success: -->
                <!-- <Setter Property="BlockIsOnlyOne" Value="{Binding ViewModelIsOnlyOne, ElementName=TheDataContext}"/> -->
            </Style>
        </Grid.Resources>
        ...
        <vc:MyBlock DataContext="{Binding PortA[0]}" />
    </Grid>
</UserControl>
MyBlock
UserControl

class MyBlock : UserControl{
    ...
    public static readonly DependencyProperty BlockIsOnlyOneProperty = DependencyProperty.Register(
        "BlockIsOnlyOne", typeof (bool), typeof (MyBlock), 
        new PropertyMetadata(default(bool), BlockIsOnlyOne_PropertyChangedCallback));

    private static void BlockIsOnlyOne_PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs a)
    {
        var @this = dependencyObject as MyBlock;
        if (@this == null) return;
        Trace.WriteLine(string.Format("Old: {0}, New: {1}", a.OldValue, a.NewValue)); // never seems to fire...
    }

    public bool BlockIsOnlyOne
    {
        get { return (bool) GetValue(BlockIsOnlyOneProperty); }
        set { SetValue(BlockIsOnlyOneProperty, value); }
    }
    ...
}

您应该能够使用。其思想是使用
AncestorType
属性搜索视图模型设置为
DataContext
的父视图。。。试试这个:

<Style TargetType="{x:Type vc:MyBlock}">
    <Setter Property="DataContext.BlockIsOnlyOne" Value="{Binding ViewModelIsOnlyOne, 
    RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
</Style>

请尝试改用相对源绑定。。。类似于
{Binding DataContext.ViewModelIsOnlyOne,RelativeSource={RelativeSource anstortype={x:Type MyNs.MyContainer}}}
。第一种语法不起作用,因为MyBlock的
DataContext
PortA[0]
,它没有名为
ViewModelIsOnlyOne
的属性,而我最好的猜测是第二种语法按名称找不到
DataContext
。。。我不确定,因为我几乎从未硬编码过这样的数据上下文。看看你是否对为什么这是个坏主意感兴趣:)看看我下面的答案-我不知道你在容器上创建DP是什么意思。。。那没必要。我们的想法是创建一个绑定,将其源代码设置为它在UI树上找到的第一个
MyNs.MyContainer
,并绑定到它的
DataContext.ViewModelIsOnlyOne
属性,该属性应该是基于您在问题中发布的内容的有效属性。它可以工作,但只有当我在容器中创建一个
依赖属性时,
。。。它不直接作用于视图模型(即,我必须在容器中创建一个DP,并人工将其绑定到容器的视图模型,它有点扭曲…)无法直接作用于视图模型,绕过容器…等等。。。这不太对。。。还在看。@Sheridan您的
DataContext.
位置不对。它应该在绑定路径中,而不是我认为的属性路径中。另外,我建议在RelativeSource绑定中使用
MyNs.MyContainer
类名,而不是泛型
UserControl
,以确保在UI层次结构中获得正确的项:)谢谢!我错过了
DataContext.
中的
Value=“{Binding DataContext.ViewModelIsOnlyOne,…
。非常感谢!
<Style TargetType="{x:Type vc:MyBlock}">
    <Setter Property="DataContext.BlockIsOnlyOne" Value="{Binding ViewModelIsOnlyOne, 
    RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
</Style>
<Style TargetType="{x:Type vc:MyBlock}">
    <Setter Property="BlockIsOnlyOne" Value="{Binding DataContext.ViewModelIsOnlyOne, 
    RelativeSource={RelativeSource AncestorType={x:Type YourPrefix:MyContainer}}}" />
</Style>