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