C# 我可以更新ObservableCollection中的值吗<;T>;不销毁和添加新项目?

C# 我可以更新ObservableCollection中的值吗<;T>;不销毁和添加新项目?,c#,wpf,C#,Wpf,我的WPF应用程序出现了这个问题——我正在使用ObservableCollection将UI绑定到播放器集合。此列表每10秒更新一次,其中包含来自游戏服务器的新数据流。问题是,删除列表并重新添加所有内容会导致一些可怕的UI不一致: 选中的项目将被取消选中 打开的上下文菜单将变得未绑定且无用 所有项目实例丢失时可能会出现一些错误 因此,我问是否有任何方法可以更新与以前的值不匹配的项的值。我仍然需要它对UI的数据绑定友好(在PropertyChanged上自动更新) 如果可以在集合中找到玩家,只

我的WPF应用程序出现了这个问题——我正在使用
ObservableCollection
将UI绑定到播放器集合。此列表每10秒更新一次,其中包含来自游戏服务器的新数据流。问题是,删除列表并重新添加所有内容会导致一些可怕的UI不一致:

  • 选中的项目将被取消选中
  • 打开的上下文菜单将变得未绑定且无用
  • 所有项目实例丢失时可能会出现一些错误

因此,我问是否有任何方法可以更新与以前的值不匹配的项的值。我仍然需要它对UI的数据绑定友好(在PropertyChanged上自动更新)

如果可以在集合中找到玩家,只需将更新的属性值映射到他们即可。如果播放机本身实现了INotifyPropertyChanged,那么它应该可以轻松工作。

如果可以在集合中找到播放机,只需将更新的属性值映射到它们即可。如果播放机本身实现了INotifyPropertyChanged,它应该可以轻松工作。

一个选项是将播放机数据提取到自己的类中,并将数据封装在包装器中。例如:

public sealed class PlayerData
{
    //Data related to the Player (possibly immutable)
}

public sealed class Player : INotifyPropertyChanged
{
    private PlayerData _data;

    //Mirror properties for information in data

    //Other functionality

    public void ChangeData(PlayerData newData)
    {
        _data = newData;
        //Trigger OnPropertyChanged(null) here to invalidate public state
    }
}

现在,您可以替换播放器的数据,而不必使外部播放器实例无效。如果仔细观察,这实际上是底层播放器模型的一种视图模型。

一个选项是将播放器数据提取到自己的类中,并将数据封装在包装器中。例如:

public sealed class PlayerData
{
    //Data related to the Player (possibly immutable)
}

public sealed class Player : INotifyPropertyChanged
{
    private PlayerData _data;

    //Mirror properties for information in data

    //Other functionality

    public void ChangeData(PlayerData newData)
    {
        _data = newData;
        //Trigger OnPropertyChanged(null) here to invalidate public state
    }
}

现在,您可以替换播放器的数据,而不必使外部播放器实例无效。如果你仔细看,这实际上是底层播放器模型的一种ViewModel。

据我所知,ObservableCollection已经实现了INotifyChange接口,因此它们被刷新。我认为代码示例在这里会非常有用。我认为ObservableCollection只会通知正在添加或删除的项目——我不认为更新集合中已有的实际项目将实现这一点。我认为项目本身必须实现INotifyPropertyChanged。据我所知,ObservableCollection已经实现了INotifyChange接口,因此它们被刷新。我认为代码示例在这里非常有用。我认为ObservableCollection只会通知添加或删除的项目——我不认为更新实际的项目已经在收集中的将实现这一点。我认为项目本身必须实现INotifyPropertyChanged。谢谢Phil。我最终做的是允许Player类实现INotifyPropertyChanged,并通过不替换项来管理项的更新,而是检查它们是否首先存在,然后使用这行代码更新它们。Player p=Team1List.Where(i=>i.PlayerName==Player.PlayerName.FirstOrDefault();然后将p设置为更新的玩家实例,并相应地进行更新。谢谢Phil。我最终做的是允许Player类实现INotifyPropertyChanged,并通过不替换项来管理项的更新,而是检查它们是否首先存在,然后使用这行代码更新它们。Player p=Team1List.Where(i=>i.PlayerName==Player.PlayerName.FirstOrDefault();然后将p设置为更新后的播放器实例,并相应地进行更新。我确实实现了该接口,但在我的情况下,如果我在更新逻辑中将该项设置为新实例,则效果最好。谢谢。我确实实现了这个接口,但在我的情况下,如果我在更新逻辑中将该项设置为一个新实例,它似乎工作得最好。谢谢