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

20

我有一个带有DataTrigger样式的TextBox,可以更改文本内容,代码如下:

<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;

3
你需要做的第一件事是打开数据绑定的调试信息:http://i.stack.imgur.com/MF8i5.png 然后重新运行程序并查看输出窗口,看看是否有错误。你可能已经这样做了;你提到snoop表明你比其他人更熟悉这方面。还可能需要在问题中提供虚拟机的相关部分。 - user1228
我会检查你的输出窗口是否有错误。可能只是绑定出了问题,很简单就能解决。 - gleng
是的,正如我所提到的:“输出中没有任何内容”。绑定错误的警告已启用。我将使用该属性更新主帖...但正如我之前提到的那样,我可以很好地绑定并显示相同属性的值,只是在触发器中无法正常工作。 - moggizx
1个回答

63

依赖属性可以从许多不同的地方设置; 在线、动画、强制、触发器等。因此,创建了一个依赖属性值优先级列表,它规定哪些更改将覆盖其他更改。由于这种优先顺序,我们不能使用触发器来更新在您的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>

5
那真是太荒谬了...这真的有充分的理由吗? - moggizx
6
我不太同意你的观点......这与依赖属性值优先级有关,因为有很多种方法可以设置DependencyProperty。如果你了解它,就更容易理解。 - Sheridan
好奇怪啊...我记得很多次在Xaml中明确设置属性,然后添加触发器就可以了。看看这个:https://stackoverflow.com/a/42000116/2830676 目前我很喜欢你的解决方案 - 它对我有用,所以+1(需要来源的解释!) - Yitzchak
我更新了我的回答以使我的观点更清晰。将属性设置为 inline 将阻止它被 Trigger 更改。在我的回答中如上所述设置是使用 Trigger 时设置属性初始值的正确方法。希望现在更清楚了。 - Sheridan
在这段代码中,当 MyBool 被设置为 false 时,Text 将再次变为 Foo,对吧?换句话说,不需要为 False 情况指定另一个 DataTrigger? - user2619824

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接