【问题标题】:WPF DataTrigger only working 1 timeWPF DataTrigger 仅工作 1 次
【发布时间】:2014-07-20 16:56:25
【问题描述】:

我正在试用 WPF,我有一个应用程序,其 ObservableCollection 连接到 ListView。它完美地添加了项目,一切都一起下降。它从实时源中获取数据,因此项目值正在更新并添加行。但现在我想要突出显示最近的行,更改文本,以显示该特定行正在更改。所以我设置了一个数据触发器,并在ObservableCollection 中的DataType 中添加了一个值,称为RecentlyChanged。如果为真,则将文本设置为红色,否则将文本设置为黑色。

当我运行此代码时,列表项变为红色,然后再也不会变回来,我已经尝试了所有方法,它让我失望了。我已经检查了调试器,即使值为no(我使用字符串yesno,因为我想尝试各种数据类型)它仍然保持红色。数据触发代码如下:

--编辑:添加到我之前尝试使用但无济于事的第二个数据触发器中。

<ListView ItemsSource="{Binding DataTable, UpdateSourceTrigger=PropertyChanged}">
    <ListView.Resources>
        <Style TargetType="ListViewItem">
            <Setter Property="Foreground" Value="Black"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=RecentlyChanged}" Value="yes">
                    <Setter Property="Foreground" Value="Red" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=RecentlyChanged}" Value="no">
                    <Setter Property="Foreground" Value="Black" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ListView.Resources>

【问题讨论】:

  • 底层数据类型是否实现了INotifyPropertyChanged?如果是这样,请确保您的控件已设置为处理来自每个项目的 PropertyChanged 事件。
  • 它没有 INotifyPropertyChanged。我想如果我只是自己设置值,它应该可以很好地处理这个问题。
  • 问题是 ObservableCollection 只检查集合本身何时发生变化,即何时添加或删除项目。项目本身需要触发事件才能触发 UI 更新。
  • 所以如果我实现了一个 INotifyPropertyChanged,那么一旦其中一个被更改并被触发,我将如何从代码中更改字体,因为列表视图是在 XML 中设置的?
  • 再想一想,我意识到您在 xaml 中的数据触发器应该负责绑定。关键是触发事件。

标签: c# wpf datatrigger


【解决方案1】:

问题在于ObservableCollection 仅报告集合本身的更改,换句话说,它会在添加或删除项目时触发CollectionChanged 事件,但不会在这些项目的属性更改时触发。为了达到预期的效果——当项目的属性发生变化时更新数据触发器——项目本身必须实现INotifyPropertyChanged接口并在设置所需的属性时触发PropertyChanged事件。

在这种情况下,您可以使用以下内容:

using System.ComponentModel;

public class ListViewItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        var propChanged = PropertyChanged;
        if(propChanged != null)
        {
            propChanged(this, new PropertyChangedEventArgs(name));
        }
    }

    private string recentlyChanged = "yes"; // Recently changed on creation
    public string RecentlyChanged
    {
        get { return recentlyChanged; }
        set {
            recentlyChanged = value;
            OnPropertyChanged("RecentlyChanged");
        }
    }

    // ... define the rest of the class as usual

}

WPF 魔法应该负责其余的工作。

【讨论】:

  • 谢谢奥斯汀,很高兴你把它放在这里,所以我可以把它作为公认的答案。非常感谢您的帮助!
猜你喜欢
  • 2018-06-19
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 2021-11-28
  • 2021-11-14
  • 1970-01-01
相关资源
最近更新 更多