Datatrigger 适当地改变了 TextBlock 的初始属性,但不是在对象改变之后

Posted

技术标签:

【中文标题】Datatrigger 适当地改变了 TextBlock 的初始属性,但不是在对象改变之后【英文标题】:Datatrigger appropriately changes the initial property of TextBlock but not after the object changes 【发布时间】:2021-05-19 17:57:12 【问题描述】:

问题

为我的文本块设置数据触发器时,它会毫无问题地接受默认值并适当地更改前景,但是,当值更改时,它不会像预期的那样更改颜色。我浏览了一些答案,我应该能够以某种方式引用相对源,但它并没有改变结果。

XAML 测试代码

            <ListBox Name="test" Width="90" Margin="20,0,20,40" MouseDown="TextBlock_MouseDownTest"
                 ScrollViewer.VerticalScrollBarVisibility="Disabled">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Name="dttBlock" Text="Binding Time" MouseDown="TextBlock_MouseDownTest">
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Style.Triggers>
                                    <DataTrigger Binding="Binding Path =Flex" Value="normal">
                                        <Setter Property="Foreground" Value="Blue" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

MouseDownClickEvent

        private void TextBlock_MouseDownTest(object sender, MouseButtonEventArgs e)
    
        TimeLord item = (TimeLord) (sender as TextBlock).DataContext;
        var textBlock = sender as TextBlock;

        switch (item.Flex)
        
            case "off":
                MessageBox.Show("Normal ON");
                item.Flex = "normal";
                break;
            case "normal":
                MessageBox.Show("Flex ON");
                item.Flex = "flex";
                break;
            case "flex":
                MessageBox.Show("OFF");
                item.Flex = "off";
                break;
        
    

先前的实施和期望的结果

如果回复的人不介意,我想对此进行更广泛的讨论。我使用数据触发器的原因是我在实现一个按钮时遇到了麻烦,该按钮将我的所有列表框项目前景重置为默认颜色(黑色)。

当前 XAML 代码

            <ListBox Name="friday" Width="90" Margin="20,0,20,40" MouseDown="TextBlock_MouseDown"
                 ScrollViewer.VerticalScrollBarVisibility="Disabled" IsSynchronizedWithCurrentItem="True">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="Binding Time" MouseDown="TextBlock_MouseDown" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

当前 C# ButtonClickEvent 代码

        private void clear_Click(object sender, RoutedEventArgs e)
    
        List<System.Windows.Controls.ListBox> weekdays = new List<System.Windows.Controls.ListBox>
            monday, tuesday, wednesday, jueves, friday;

        for (var i = 0; i < weekdays.Count; i++)
        
            foreach (TimeLord item in weekdays[i].Items)
            
                item.Flex = "off";
            
        
    

我在更改与 listboxitem 关联的对象时没有问题,但我无法从按钮本身更改前景。我可以通过使用传递给事件的发送者创建一个事件来成功更改前景。如果有一种方法可以让我从 ButtonClick 事件访问文本框,那可能是 Datatrigger 的替代解决方案。

This is a small clip 炫耀旧的实现,我目前可以更改项目的值。

【问题讨论】:

TimeLord 是否实现 INotifyPropertyChanged 就是这样!谢谢,我会更新我的帖子以显示我对班级所做的更改。 【参考方案1】:

在我的 TimeLord 类中,我从未实现过 INotifyPropertyChanged,在这样做之后,一切都按照我对 DataTriggers 的预期工作。

TimeLord.cs

public class TimeLord : INotifyPropertyChanged 
protected void OnPropertyChanged(PropertyChangedEventArgs e)

    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
        handler(this, e);


public string flex;
public string Flex

    get  return flex;
    set
    
        flex = value;
        OnPropertyChanged();
    


public string Time

    get;
    set;


public event PropertyChangedEventHandler PropertyChanged;

[NotifyPropertyChangedInvocator]
public void OnPropertyChanged([CallerMemberName] string propertyName = null)

    if (PropertyChanged != null)
    
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    



XAML 代码块(和以前一样,只是为了显示不止一种触发器类型)

<DataTemplate>
                    <TextBlock Name="dttBlock" Text="Binding Time" MouseDown="TextBlock_MouseDownTest">
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Style.Triggers>
                                    <DataTrigger Binding="Binding Path =Flex" Value="normal">
                                        <Setter Property="Foreground" Value="Blue" />
                                    </DataTrigger>
                                    <DataTrigger Binding="Binding Path =Flex" Value="flex">
                                        <Setter Property="Foreground" Value="Red" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                </DataTemplate>

【讨论】:

以上是关于Datatrigger 适当地改变了 TextBlock 的初始属性,但不是在对象改变之后的主要内容,如果未能解决你的问题,请参考以下文章

将 DataTrigger 绑定到复选框的 IsChecked 属性

WPF ItemsControl DataTrigger EnterActions动画未启动

如何将参数传递给 DataTrigger?

消除重复的 DataTrigger 逻辑

[WPF 学习] 13.DataTrigger之EnterAction和ExitAction

绑定属性上的 DataTrigger