保留列表框项目选择

时间:2009-04-08 14:55:31

标签: c# collections listbox filtering selection

首先是代码(抱歉,如果它不是100%)我不是专家,然后问题如下。

    public partial class Window1 : Window
    {
    CollectionView cv;

    public Window1()
    {
        InitializeComponent();

        List<Person> ppl = new List<Person>();
        BitmapImage b = new BitmapImage(new Uri(@"http://i.stackoverflow.com/Content/Img/stackoverflow-logo-250.png",UriKind.Absolute));
        ppl.Add(new Person(b, "world1"));
        ppl.Add(new Person(b, "world2"));
        ppl.Add(new Person(b, "world3"));
        ppl.Add(new Person(b, "world4"));
        ppl.Add(new Person(b, "world5"));
        ppl.Add(new Person(b, "world6"));

        lb.ItemsSource = ppl;
        lb.SelectedIndex = 1;

        cv = (CollectionView)CollectionViewSource.GetDefaultView(lb.ItemsSource);

        new TextSearchFilter(cv, textBox1);
    }
}

public class TextSearchFilter
{
    public TextSearchFilter(CollectionView cv, TextBox tb)
    {
        string filterText = "";

        cv.Filter = delegate(object obj)
        {
            Person p = obj as Person;
            int index = p.Info.IndexOf(filterText,0,StringComparison.InvariantCultureIgnoreCase);
            return index > -1;
        };

        tb.TextChanged += delegate
        {
            filterText = tb.Text;
            cv.Refresh();
        };
    }
}

    class Person
    {
        private BitmapImage myImage;
        private string myInfo = "";

        public BitmapImage Image
        {
            get { return myImage; }
            set { myImage = value; }
        }

        public string Info
        {
            get { return myInfo; }
            set { myInfo = value; }
        }

        public Person(BitmapImage Image, string Info)
        {
            this.Image = Image;
            this.Info = Info;
        }
    }

感谢您阅读目前为止,正如您现在所理解的那样,代码会根据文本框中的输入过滤列表框,其效果就像魅力btw。

我的问题是如何在过滤期间保留选择。当窗口加载时,列表框中包含所有项目,我选择第一项,然后我在文本框中键入内容,列表框过滤器只显示相关项目,选择另一项后我删除文本中的所有文本将它恢复到原始状态的框,但这次选择仅更改为我在过滤视图中选择的项目(因此,显示为选中的两个项目仅显示为选中的一个项目)。这种行为很明显,因为我正在过滤集合,所以当集合发生更改时,选择将丢失。

有没有办法保留选择?任何指针?

非常感谢。

2 个答案:

答案 0 :(得分:1)

可能在你的TextChanged事件处理程序中,你应该存储ListBox的选定项目,如下所示:

Person[] selectedPeople = new Person[lb.SelectedItems.Count];
lb.SelectedItems.CopyTo(selectedPeople, 0);

然后在刷新过滤器后,使用以下命令将其添加回来:

foreach (Person p in selectedPeople)
{
    if(lb.Items.Contains(p))
    {
        lb.SelectedItems.Add(p);
    }
}

我之所以使用CopyTo并保存在数组中而不仅仅是使用:

IList selectedPeople = lb.SelectedItems;

是后者只保留对lb.SelectedItems的引用,而foreach会修改枚举,导致抛出异常。可能有一种更简单的方法,但这应该让你朝着正确的方向前进。

答案 1 :(得分:0)

我的猜测是过滤器会插入,删除和重新排列可观察集合中的项目。当它暂时删除一个以将其插入其他地方时,WPF会过早地将SelectedItem设置为null。然后,当您重新添加时,它将不会被选中。

以下是您可以附加到列表框的行为形式的解决方法。

http://www.codeproject.com/Tips/802806/Preserve-the-Selected-Item-of-a-WPF-List-Box