我如何合并两个 Observable 集合,只从新列表中获取新的和更改的项目,并将其添加到旧列表中?
How can I merge two Observable Collections, taking only the new and changed items from the new list, and add it to the old list?
我有一个 WPF 应用程序,它使用绑定到 ObservableCollection 的 DataGrid 元素:
ObservableCollection<Deployment> deployments = DataAccess.GetDeployments();
datagrid01.ItemsSource = deployments;
这是一个部署 class。 Deployment 对象表示现场发生的 Windows 安装,因此像 CurrentTime 这样的东西经常变化。
class Deployment
{
public string UniqueID { get; set; }
public string ComputerName { get; set; }
public string IPAddress { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public string UserName { get; set; }
public string TaskSequenceName { get; set; }
public string MachineObjectOU { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? CurrentTime { get; set; }
public string Status { get; set; }
}
我想定期用对这些对象的任何更改更新 DataGrid,例如 CurrentTime 或它们的状态。安装完成后状态变为 3,如果处于错误状态则状态变为 2。
所以,我可以在计时器上获得一个新的对象集合,但是仅将这个新集合中的新项目添加到 DataGrid 并更改具有更新时间的现有项目的最佳方法是什么,或状态,或其他什么?
使用 INotifyPropertyChange
界面将 ObservableCollection<Deployment>
设为 属性,将 Raise
设为 property change event
。然后,您可以将此 属性 绑定到 xaml
本身中的 DataGrid
的 itemsource
。因此,您的 collection
从 UI
或 Database
发生的任何变化,整个 list
都会自动刷新。
如下所示的方法应该可以完成这项工作。它不会替换 deployments
集合中的现有项目,而只是更新项目的属性。
为了使 UI 更新,Deployment
class 必须实现 INotifyPropertyChanged
接口并在 PropertyChanged
属性 值发生变化。一个简单的解决方案是添加一个 UpdateFrom(Deployment d)
方法,该方法更新所有属性,然后使用 null
作为 属性 名称引发单个 PropertyChanged 事件(以通知所有属性已更改)。
using System.Linq;
...
private void UpdateDeployments(IEnumerable<Deployment> changedDeployments)
{
foreach (var changedDeployment in changedDeployments)
{
var deployment = deployments.FirstOrDefault(
d => d.UniqueID == changedDeployment.UniqueID);
if (deployment != null)
{
deployment.UpdateFrom(changedDeployment);
}
else
{
deployments.Add(changedDeployment);
}
}
}
使用 .Except() 方法从 ObservableCollection 中过滤项目
newRecordings = recordings.Except(_recordingsHidden).ToList();
我有一个 WPF 应用程序,它使用绑定到 ObservableCollection 的 DataGrid 元素:
ObservableCollection<Deployment> deployments = DataAccess.GetDeployments();
datagrid01.ItemsSource = deployments;
这是一个部署 class。 Deployment 对象表示现场发生的 Windows 安装,因此像 CurrentTime 这样的东西经常变化。
class Deployment
{
public string UniqueID { get; set; }
public string ComputerName { get; set; }
public string IPAddress { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public string UserName { get; set; }
public string TaskSequenceName { get; set; }
public string MachineObjectOU { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? CurrentTime { get; set; }
public string Status { get; set; }
}
我想定期用对这些对象的任何更改更新 DataGrid,例如 CurrentTime 或它们的状态。安装完成后状态变为 3,如果处于错误状态则状态变为 2。
所以,我可以在计时器上获得一个新的对象集合,但是仅将这个新集合中的新项目添加到 DataGrid 并更改具有更新时间的现有项目的最佳方法是什么,或状态,或其他什么?
使用 INotifyPropertyChange
界面将 ObservableCollection<Deployment>
设为 属性,将 Raise
设为 property change event
。然后,您可以将此 属性 绑定到 xaml
本身中的 DataGrid
的 itemsource
。因此,您的 collection
从 UI
或 Database
发生的任何变化,整个 list
都会自动刷新。
如下所示的方法应该可以完成这项工作。它不会替换 deployments
集合中的现有项目,而只是更新项目的属性。
为了使 UI 更新,Deployment
class 必须实现 INotifyPropertyChanged
接口并在 PropertyChanged
属性 值发生变化。一个简单的解决方案是添加一个 UpdateFrom(Deployment d)
方法,该方法更新所有属性,然后使用 null
作为 属性 名称引发单个 PropertyChanged 事件(以通知所有属性已更改)。
using System.Linq;
...
private void UpdateDeployments(IEnumerable<Deployment> changedDeployments)
{
foreach (var changedDeployment in changedDeployments)
{
var deployment = deployments.FirstOrDefault(
d => d.UniqueID == changedDeployment.UniqueID);
if (deployment != null)
{
deployment.UpdateFrom(changedDeployment);
}
else
{
deployments.Add(changedDeployment);
}
}
}
使用 .Except() 方法从 ObservableCollection 中过滤项目
newRecordings = recordings.Except(_recordingsHidden).ToList();