【问题标题】:How to mimick the behaviour of an ObservableCollection for a List when it is a Source for a CollectionViewSource?当它是 CollectionViewSource 的源时,如何模仿 List 的 ObservableCollection 的行为?
【发布时间】:2009-11-03 13:40:03
【问题描述】:

以下代码的工作方式如下:显示一个带有排序名称列表的表单。单击按钮时,新名称将添加到列表中文本框的适当排序位置。当双击列表中的一个项目时,它会以“AAA”为前缀,这会触发它被放置在列表的顶部。 当我将 ObservableCollection 更改为 List 时,这种行为当然会消失。但是我怎么能模仿呢???我尝试实现 INotifyPropertyChanged,我在列表框的 BindingExpression 上调用了 UpdateTarget() 方法,都无济于事...

我有以下 XAML:

<Window x:Class="CollectionViewSpike.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel>
    <TextBox Name="NewNameBox" Text="{Binding NewName, UpdateSourceTrigger=PropertyChanged}"/>
    <Button Click="Button_Click"">Add</Button>
    <ListBox Name="listbox" ItemsSource="{Binding MyCollectionViewSource.View}"
             MouseDoubleClick="listbox_MouseDoubleClick"/>
</StackPanel>

背后的代码:

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;

namespace CollectionViewSpike
{
   public partial class Window1: Window
   {
    public ObservableCollection<string> Names { get; set; }

    public static DependencyProperty NewNameProperty = DependencyProperty.Register("NewName", typeof (string),
                                                                           typeof (Window1),
                                                                           new PropertyMetadata(string.Empty));

    public string NewName
    {
        get { return (string) GetValue(NewNameProperty); }

        set{ SetValue(NewNameProperty,value);}
    }

    public Window1()
    {
        InitializeComponent();
        var names = new string[] { "onno", "friso","andre"};
        Names = new ObservableCollection<string>(names);
        collectionViewSource = new CollectionViewSource { Source = Names };
        collectionViewSource.SortDescriptions.Add(
                     new SortDescription("", ListSortDirection.Ascending));
        DataContext = this;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        NewName = NewName ?? "???";
        Names.Add(NewName);
        NewName = string.Empty;
    }

    private CollectionViewSource collectionViewSource;
    public CollectionViewSource MyCollectionViewSource
    {
        get { return collectionViewSource; }
        private set { collectionViewSource = value;}
    }

    private void listbox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        var user = (string)listbox.SelectedItem;
        int index = Names.IndexOf(user);
        Names[index]="AAA"+Names[index];
    }
}

}

【问题讨论】:

    标签: .net wpf data-binding collectionviewsource


    【解决方案1】:

    我不确定您为什么不只使用 ObservableCollection - 这就是它的用途。但是,无论如何,您可能还必须实现 INotifyCollectionChanged 以让绑定知道内容或顺序已更改。

    msdn reference for ObservableCollection

    【讨论】:

    • 给出的代码是仍然暴露问题的最佳简化。我需要找到如何让列表框在 Button_click en MouseDoubleClick 方法中更新其内容
    【解决方案2】:

    找到了。将 MyCollectionViewSource.View.Refresh() 添加到更改底层不可观察 enumerable&lt;T> 的方法中 假设 Observable&lt;string> Names 现在是 List&lt;string> Names:

       private void Button_Click(object sender, RoutedEventArgs e)
        {
            NewName = NewName ?? "???";
            Names.Add(NewName);
            NewName = string.Empty;
            MyCollectionViewSource.View.Refresh();
        }
    
       private void listbox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var user = (string)listbox.SelectedItem;
            int index = Names.IndexOf(user);
            Names[index]="AAA"+Names[index];
            MyCollectionViewSource.View.Refresh();
        } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-14
      • 2014-06-22
      • 1970-01-01
      • 2022-01-23
      • 2020-07-14
      • 2010-09-25
      相关资源
      最近更新 更多