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

时间:2017-04-28 07:56:18

标签: c# observablecollection inotifypropertychanged

我有一个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));
}

2 个答案:

答案 0 :(得分:1)

将新卡车添加到Observeable集合后,您可以启动任务或线程,传递卡车列表,然后让任务睡眠所需的时间。然后,您可以将属性从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;
        }                                      
});

答案 1 :(得分:1)

既然你说的是Model,Bindings和ObservableCollections等,我假设你在这里使用MVVM模式?

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

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

确保您的Truck类也实现了INotifyPropertyChanged - 在该bool属性的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. 
     }
 }

您如何触发更改Truck实体的代码?使用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;
        }
    }
 }