更新C#中的可观察集合并更改列表视图中文本的颜色
我有一个更新C#中的可观察集合并更改列表视图中文本的颜色,c#,observablecollection,inotifypropertychanged,C#,Observablecollection,Inotifypropertychanged,我有一个可观测集合,它包含不同的属性值。我的XAML中有一个列表视图,它绑定到可观察集合 在列表视图中,我有一个标签,它有一个绑定到属性的属性TextColor。从下面的代码片段中可以看出,有一个值为false。这表示标签中的文本应为红色 我想要实现的是,在一段时间间隔后,将false的值改为true,比如说5秒。标签中相应的TextColor颜色为蓝色 请注意,我已经在模型中实现了INotifyPropertyChanged。有人能帮我模拟一下上面的内容吗 ObservableCollecti
可观测集合
,它包含不同的属性值。我的XAML中有一个列表视图
,它绑定到可观察集合
在列表视图
中,我有一个标签,它有一个绑定到属性的属性TextColor
。从下面的代码片段中可以看出,有一个值为false。这表示标签中的文本应为红色
我想要实现的是,在一段时间间隔后,将false的值改为true,比如说5秒。标签中相应的TextColor
颜色为蓝色
请注意,我已经在模型中实现了INotifyPropertyChanged。有人能帮我模拟一下上面的内容吗
ObservableCollection detectedTruck=新的ObservableCollection()
将新卡车添加到可观察集合后,您可以启动任务或线程,传递卡车列表,然后让任务休眠所需的时间。然后可以将属性从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;
}
});
既然您在谈论模型、绑定和可观察集合等,我假设您在这里使用的是MVVM模式
ObservableCollection<Truck> DetectedTrucks = new ObservableCollection<Truck>();
for (int i = 0; i<12; i++)
DetectedTrucks.Add(new Truck(1, "Truck" + i, false));
确保ListBox(或ListView)的ItemsSource已绑定到您的集合
<ListBox ItemsSource="{Binding DetectedTrucks}" ...
您是如何触发更改卡车实体的代码的?在UI中使用按钮?如果是这样,我会使用RelayCommand
<Button Command="{Binding ChangeTrucksCommand}" ...
你能给我举个例子吗?添加这样的内容:Task.Factory.StartNew(()=>{Thread.Sleep(5000);foreach(truck in detectedTruck){truck.PropertyToChange=true;}});在一个单独的线程上更改一个模型,而不进行必要的保护(如锁),这无疑会导致竞争条件/数据损坏。但是当我应用代码并运行应用程序时。所有项目的颜色都已更改。我想看到颜色效果一个接一个地改变。请告知我如何实现此目的。您缺少转让财产的OnProperty更改!您在哪里调用
await changeTrackAsync()
,也要添加这样做的主要调用方必须是Async
,否则您不能等待异步方法我正要问这个问题,我仍然在编辑我的答案。用例也需要changeTrackAsync
在特定的时间段后调用,我假设还需要重复调用。类似于计时器线程所做的事情@jones,Async-Await使用调用同步上下文(此处为UI上下文)确保更新,因此永远不会出现线程安全问题。作品如魅力:)
private bool _transfer;
public bool Transfer
{
get { return _transfer; }
set { _transfer = value; OnPropertyChanged(nameof(Transfer)); }
}
<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.
}
}
<Button Command="{Binding ChangeTrucksCommand}" ...
private RelayCommand _changeTrucksCommand;
public RelayCommand ChangeTrucksCommand
{
get
{
if (_changeTrucksCommand == null)
_changeTrucksCommand = new RelayCommand(async o => await ChangeTrucksAsync());
return _changeTrucksCommand;
}
}
}