在 C# 中更新 Observable 集合并更改列表视图中文本的颜色

Updating an Observable Collection in C# and change color of text in list view

我有一个 ObservableCollection,其中包含不同的属性值。我的 XAML 中有一个 Listview,它绑定到 ObservableCollection

ListView 中,我有一个带有 属性 TextColor 的标签,它绑定到 属性。从下面的代码片段中可以看出,有一个值 false。这表示标签中的文本应为红色。

我想要实现的是在一段时间后将这个 false 值更改为 true,比如说 5 秒。而标签中对应的 TextColor 颜色为蓝色。

请注意,我已经在我的模型中实现了 INotifyPropertyChanged。有人可以帮我模拟上面的内容吗?

ObservableCollection detectedTruck= new ObservableCollection();

        for (int i = 0; i<12; i++)
        {
            detectedTruck.Add(new Truck(i, "Truck" + i, "5555", false));
        }

            listView.ItemsSource = detectedTruck;

            Task.Factory.StartNew(() =>
            {

                Thread.Sleep(5000);
                foreach (var tags in detectedTruck)
                {
                    Thread.Sleep(500);
                    tags.Transfer = true;
                }
            });

在我的模型中:

public event PropertyChangedEventHandler PropertyChanged;

private int _id;

public int Id
{
    get { return _id; }
    set
    {
        _id = value;
        OnPropertyChanged();
    }
}

private string _uid;
public string UID
{
    get { return _uid; }
    set
    {
        _uid = value;
        OnPropertyChanged();
    }
}

public bool Transfer { get; set; }

private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

将新卡车添加到 Observable 集合后,您可以启动任务或线程,传递卡车列表,然后让任务休眠所需的时间。然后您可以将 属性 从 false 更改为 true。

Task.Factory.StartNew(() =>
{                           

    Thread.Sleep(Delay before first change in ms);
        foreach (truck in detectedTruck )
        {
               Thread.Sleep(Delay between the items);
               truck.PropertyToChange = true;
        }                                      
});

既然你在谈论模型、绑定和 ObservableCollections 等,我假设你在这里使用 MVVM 模式?

ObservableCollection<Truck> DetectedTrucks = new ObservableCollection<Truck>();

for (int i = 0; i<12; i++)
    DetectedTrucks.Add(new Truck(1, "Truck" + i,  false));

确保您的 Truck class 也实现了 INotifyPropertyChanged - 在那个 bool 属性 Transfer 的 setter 中您应该调用 OnProperyChanged(nameof(Transfer))

private bool _transfer;

public bool Transfer
{
    get { return _transfer; }
    set { _transfer = value; OnPropertyChanged(nameof(Transfer)); }
}

确保您的 ListBox(或 ListView)的 ItemsSource 已绑定到您的集合。

<ListBox ItemsSource="{Binding DetectedTrucks}" ... 

调用更新实体的异步方法。

 private async Task ChangeTrucksAsync()
 {
     foreach (Truck t in DetectedTrucks)
     {
         t.Transfer = true; // this also calls OnProperyChanged(nameof(Transfer))
        // WPF will  reevaluate the binding, and your XAML style/value converter then changes the color to Blue

         await Task.Delay(500); // return to UI thread for 500ms, updating items one by one. 
     }
 }

您如何触发更改卡车实体的代码? 使用 UI 中的按钮?如果是这样,我会使用 RelayCommand;

<Button Command="{Binding ChangeTrucksCommand}" ...

最后在您的 ViewModel 中;

private RelayCommand _changeTrucksCommand;

public RelayCommand ChangeTrucksCommand
{
    get
    {
        if (_changeTrucksCommand == null)
            _changeTrucksCommand = new RelayCommand(async o => await ChangeTrucksAsync());

            return _changeTrucksCommand;
        }
    }
 }