代码之家  ›  专栏  ›  技术社区  ›  Ben Gribaudo

替换ListView的ItemsSource而不丢失SelectedItem

  •  1
  • Ben Gribaudo  · 技术社区  · 14 年前

    你能推荐一种方法来避免下面这些方法的缺点,同时仍然允许vm将这些数据插入ListView而不会导致ListView丢失SelectedItem吗?

    谢谢您,


    一种简单的方法(视图模型代码;ListView的SelectedItem&ItemsSource绑定到vm上相同的绑定属性):

    var selectedItem = SelectedItem;
    ItemsSource = service.GetData();
    SelectedItem = Accounts.SingleOrDefault(x => x.Equals(selectedItem));
    

    这种方法看起来很难看。它还涉及重置SelectedItem——如果更改SelectedItem会更改主详细信息窗体上的详细信息编辑,则这是一个潜在的问题(ItemsSource的设置会导致SelectedItem被清除,这就是为什么它会在最后一行被重新设置。)

    2 回复  |  直到 14 年前
        1
  •  0
  •   naacal    14 年前

    隐马尔可夫模型。。。怎么样:

    <ListView Name="listView" SelectionChanged="listView_SelectionChanged" DataContextChanged="listView_DataContextChanged" />
    

    在SelectionChanged处理程序中,将SelectedItem保存在ListView的标记中

    private void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        (sender as ListView).Tag = (sender as ListView).SelectedItem;
    }
    

    ListView的DataContext更改后,根据新集合计算保存在标记中的最后一个SelectedItem,并从该集合中设置新项:

        private void listView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            List<CustomClass> newList = e.NewValue as List<CustomClass>;
            if (newList != null && (sender as ListView).Tag != null)
            {
                foreach (CustomClass cClass in newList)
                    if (cClass.Equals((sender as ListView).Tag as CustomClass))
                        (sender as ListView).SelectedItem = cClass;
            }
        }
    
        2
  •  0
  •   Ben Gribaudo    14 年前

    最后,我编写了映射程序代码,加载了一个observeCollection,其中的代理对象指向从服务层检索到的真实对象。每次从服务层获取更新时,映射程序代码都会根据需要添加/删除/更新代理对象。