Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过ListCollectionView的ObservableCollection显示不正确的项目列表_C#_Wpf_Data Binding_Observablecollection_Listcollectionview - Fatal编程技术网

C# 通过ListCollectionView的ObservableCollection显示不正确的项目列表

C# 通过ListCollectionView的ObservableCollection显示不正确的项目列表,c#,wpf,data-binding,observablecollection,listcollectionview,C#,Wpf,Data Binding,Observablecollection,Listcollectionview,C#: 公共部分类主窗口:窗口 { 私有只读ViewModel虚拟机; 公共主窗口() { 初始化组件(); vm=新的ViewModel(); DataContext=vm; } 私有无效按钮\u单击(对象发送者,路由目标e) { vm.Models.RemoveAt(0); } } 公共类视图模型 { 公共可观测集合模型{get;set;} 公共ListCollectionView视图{get;set;} 公共视图模型() { 模型=新的ObservableCollection() { 新模

C#:

公共部分类主窗口:窗口
{
私有只读ViewModel虚拟机;
公共主窗口()
{
初始化组件();
vm=新的ViewModel();
DataContext=vm;
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
vm.Models.RemoveAt(0);
}
}
公共类视图模型
{
公共可观测集合模型{get;set;}
公共ListCollectionView视图{get;set;}
公共视图模型()
{
模型=新的ObservableCollection()
{
新模型(){Name=“Gordon Freeman”},
新模型(){Name=“Isaac Kleiner”},
新模型(){Name=“Eli Vance”},
新模型(){Name=“Alyx Vance”},
};
Models.CollectionChanged+=(s,e)=>View.Refresh();
视图=新ListCollectionView(模型);
}
}
公共类模型
{
公共字符串名称{get;set;}
公共重写字符串ToString()
{
返回名称;
}
}
XAML:


点击
ObservaleCollection包含4个元素,ListBox按预期显示所有4个元素。单击按钮时,将删除ObservableCollection的第一个元素。然而,列表框现在只显示第二个和第三个。看起来第1个和第4个已被删除

如果行
Models.CollectionChanged+=(s,e)=>View.Refresh()在<代码>视图=新建ListCollectionView(模型)之后移动(或完全注释掉)事情按预期进行

为什么?


另外,这是一个更大的谜题中的一个简单部分。在这个小示例中,我意识到我不需要调用
View.Refresh()已更改,列表框将自动更新。

我猜想刷新会干扰视图的自动更新。可能视图在构造函数中也订阅了
CollectionChanged
,因此如果在视图执行并调用refresh之前订阅了事件,则在集合更改和视图自己的更新之间会得到不需要的更新

e、 g

项目0已删除->通知事件侦听器
=>处理程序:刷新()->重建视图=>项被删除。
=>查看处理程序:事件参数显示:项目X已删除->删除项目X

这仍然不能解释为什么第一个和最后一个项目被删除,但对我来说似乎是合理的

如果订阅在视图实例化之后:

项目0已删除->通知事件侦听器
=>查看处理程序:事件参数显示:项目X已删除->删除项目X

=>处理程序:Refresh()->Rebuild view=>没有任何更改。

ListView刷新似乎有问题。如果将labe/TextBlock绑定到ListView.Items.Count,您将看到列表中仍有3个项目(第一次删除后)。

请尝试不要使用new关键字定义您的新实例
listCollectionView
。改用以下方法

public partial class MainWindow : Window
{
    private readonly ViewModel vm;

    public MainWindow()
    {
        InitializeComponent();
        vm = new ViewModel();

        DataContext = vm;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        vm.Models.RemoveAt(0);
    }
}

public class ViewModel
{
    public ObservableCollection<Model> Models { get; set; }
    public ListCollectionView View { get; set; }

    public ViewModel()
    {
        Models = new ObservableCollection<Model>()
        {
            new Model() { Name = "Gordon Freeman" },
            new Model() { Name = "Isaac Kleiner" },
            new Model() { Name = "Eli Vance" },
            new Model() { Name = "Alyx Vance" },
        };

        Models.CollectionChanged += (s, e) => View.Refresh();
        View = new ListCollectionView(Models);
    }
}

public class Model
{
    public string Name { get; set; }

    public override string ToString()
    {
        return Name;
    }
}

即使您正在将
模型
类包装在
可观察集合
中,您仍然需要为其实现
INotifyPropertyChanged
。我已经多次碰到这个问题,现在我记得从最低的构建块,即
Model
开始进行故障排除

var sortedCities  = CollectionViewSource.GetDefaultView(Models);
另外,在您的
视图模型中
,当
INotifyPropertyChanged
正确实现时,您不需要下面的行<代码>INotifyPropertyChanged
将为您更新UI

public class Model : INotifyPropertyChanged
{
    #region INotify Implementation
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
    #endregion

    public string _Name;
    public string Name {
        get { return _Name;  }
        set { _Name = value; NotifyPropertyChanged("Name"); }

    }
    public override string ToString()
    {
        return Name;
    }
}

这听起来不错,但我想我们还不能确定…为什么最后一项会被删除?您能解释一下原因吗?CollectionViewSource跟踪Ilist集合的所有视图。使用new将创建集合视图的新实例,并将其添加到CollectionViewSource。使用GetDefaultView将为您提供集合的默认视图,并保护您的代码不具有多个视图。因此,您可以在单个视图上添加排序和筛选。
    Models.CollectionChanged += (s, e) => View.Refresh();
    View = new ListCollectionView(Models);