绑定到 DataContext 的 WPF 样式 DataTrigger 不起作用

Posted

技术标签:

【中文标题】绑定到 DataContext 的 WPF 样式 DataTrigger 不起作用【英文标题】:WPF Style DataTrigger with binding to DataContext not working 【发布时间】:2013-10-19 14:20:04 【问题描述】:

我有一个 TextBox,其样式有一个 DataTrigger 可以更改文本,如下所示:

<Grid>
    <TextBlock Text="Foo">
        <TextBlock.Style>
            <Style BasedOn="StaticResource TextStyle" TargetType="TextBlock">
                <Style.Triggers>
                    <DataTrigger Binding="Binding MyBool" Value="True">
                        <Setter Property="Text" Value="Bar"/>
                    </DataTrigger>
                 </Style.Triggers>
             </Style>
         </TextBlock.Style>
     </TextBlock>
</Grid>

但它不起作用,文本永远不会变为“Bar”。我已经使用另一个 TextBlock 与 Text="Binding MyBool" 进行了测试,并且此文本从“False”变为“True”。 Snoop 没有显示我可以看到的错误,并且输出中没有任何内容。

这个问题似乎与WPF Trigger binding to MVVM property 重复,但我的代码似乎与那里接受的答案(http://www.thejoyofcode.com/Help_Why_cant_I_use_DataTriggers_with_controls_in_WPF.aspx,“使用样式”部分)在任何相关方面都没有不同。并且按照实际答案中的建议使用 DataTemplate 似乎是错误的,因为我只希望它适用于单个 TextBlock,但如果它是正确的,我不确定如何为此编写 DataTemplate...

编辑:

这是我绑定的属性的样子:

public bool MyBool

    get  return _myBool; 
    set
    
        if (_myBool== value)
            return;

        _myBool= value;
        NotifyPropertyChanged();
    

private bool _myBool;

【问题讨论】:

您需要做的第一件事是打开数据绑定的调试消息:i.stack.imgur.com/MF8i5.png 接下来,重新运行并检查输出窗口,看看有什么错误。你可能已经这样做了;您提到 snoop 的事实表明您遥遥领先。可能还需要问题中 VM 的相关部分。 我会检查您的输出窗口是否有错误。这可能就像绑定被搞砸一样简单。 是的,正如我所提到的:“输出中没有任何内容”。绑定错误警告已启用。我将使用该属性更新主帖子...但正如我也提到的,我可以很好地绑定并显示同一属性的值,它只是在触发器中不起作用。 【参考方案1】:

可以从许多不同的地方设置依赖属性;内联、动画、强制、触发器等。因此创建了一个Dependency Property Value Precedence 列表,这决定了哪些更改会覆盖哪些其他更改。由于这种优先顺序,我们不能使用 Trigger 来更新在 XAML 中内联显式设置的属性。试试这个:

<Grid>
    <TextBlock>
        <TextBlock.Style>
            <Style BasedOn="StaticResource TextStyle" TargetType="TextBlock">
                <!-- define your default value here -->
                <Setter Property="Text" Value="Foo" />
                <Style.Triggers>
                    <DataTrigger Binding="Binding MyBool" Value="True">
                        <!-- define your triggered value here -->
                        <Setter Property="Text" Value="Bar" />
                    </DataTrigger>
                 </Style.Triggers>
             </Style>
         </TextBlock.Style>
     </TextBlock>
</Grid>

【讨论】:

现在这太傻了……这真的有充分的理由吗? 我不同意你的观点......这完全是关于Dependency Property Value Precedence,因为有很多方法可以设置DependencyProperty。如果您意识到这一点,那就更有意义了。 这太奇怪了。我记得很多次我在 Xaml 中显式设置了一个属性,然后添加了一个触发器,它就起作用了。看看这个:***.com/a/42000116/2830676 现在我很喜欢你的解决方案 - 它对我有用,所以 +1 解决方案(解释需要来源!) 我更新了我的答案以使我的观点更清楚。设置属性 inline 将阻止它被Trigger 更改。在我的答案中设置它是使用Trigger 时为属性设置初始值的正确方法。我希望现在更清楚了。 在这段代码中,当MyBool设置为false时,Text会再次变成Foo对吗?或者说,对于 False 的情况,就不需要再指定另一个 DataTrigger 了?

以上是关于绑定到 DataContext 的 WPF 样式 DataTrigger 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

DataGrid中的WPF绑定到DataContext

C# WPF 数据绑定DataContext;Window_Loaded时进行过数据绑定,指定DataContext;触发另一事件?

我的 WPF 自定义控件 Datacontext 正在取代父母

WPF中利用控件的DataContext属性为多个TextBox绑定数据

MVVM从TabControl绑定到Page.DataContext

设置DataContext后WPF依赖属性两种方式绑定不起作用[重复]