我目前正在使用可观察集合来存储 ListView 的数据对象。将新对象添加到集合中效果很好,并且 listView 会正确更新。但是,当我尝试更改集合中某个对象的属性之一时,listView 将无法正确更新。例如,我有一个可观察的集合 DataCollection。我试试
_DataCollections.ElementAt(count).Status = "Active";
由于按下按钮,我在长时间操作之前执行此更改。 listView 不会反射(reflect)更改。所以我添加了myListView.Items.Refresh()
;。这是有效的,但是 listView 在 button_click 方法完成之前不会刷新,这在那时是不好的。
例如:
button1_Click(...)
{
_DataCollections.ElementAt(count).Status = "Active";
myListView.Items.Refresh();
ExecuteLongOperation();
_DataCollections.ElementAt(count).Status = "Finished";
myListView.Items.Refresh();
}
状态永远不会变为“Active”,方法完成后会直接变为“Finished”。 我也尝试过使用这样的调度程序:
button1_Click(...)
{
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
(NoArgDelegate)delegate { _DataCollection.ElementAt(count).Status = "Active"; myListView.Items.Refresh(); });
ExecuteLongOperation();
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
(NoArgDelegate)delegate { _DataCollection.ElementAt(count).Status = "Finished"; myListView.Items.Refresh(); });
}
但是,这似乎也不能正常工作。任何提示或想法将不胜感激。
最佳答案
您必须使用适当的数据绑定(bind)技术,然后它会自动运行。
必需...
- 在 ObservableCollection 中的类上实现 INotifyPropertyChanged(并确保在该类上设置属性时触发事件)
- 在您的 ListView 的 ItemTemplate 上,确保您正在使用绑定(bind)到属性
如果您执行了这两件事,就不需要“刷新”调用或其他任何操作。设置触发 INotifyPropertyChanged 的属性将导致 ItemTemplate 的绑定(bind)更新。
在 ObservableCollection 中的类上实现 INotifyPropertyChanged...(如果您还不知道,请查找 BindableBase 类)
public class ToDoItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _name;
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
private DateTime _date;
public DateTime Date
{
get { return _date; }
set { SetProperty(ref _date, value); }
}
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
{
if (object.Equals(storage, value)) return false;
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged(string propertyName)
{
var eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
您的 ListView
<ListView
x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock
Text="{Binding Name}"/>
<TextBlock
Text="{Binding Date}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
您的 ObservableCollection...
private ObservableCollection<ToDoItem> _toDoItems = new ObservableCollection<ToDoItem>();
// Assign the collection to the ListView
listView.ItemsSource = _toDoItems;
向收藏作品中添加东西...
_toDoItems.Add(new ToDoItem()
{
Name = "Item " + (_toDoItems.Count + 1),
Date = DateTime.Now
});
更新,你所要求的,有效...
ToDoItem item = _toDoItems[randomIndex];
item.Name = "Updated " + item.Name;
item.Date = DateTime.Now;
没有调用“刷新”或任何其他需要的。项目本身会更新,而列表不会更改。
更新第 4 项之前...
更新第 4 项后...
此处提供完整代码示例: CODE SAMPLE
关于c# - ListView 未使用 ObservableCollection 正确更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6542035/