1

首先是代码(对不起,如果不是 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;
        }
    }

感谢您到目前为止的阅读,正如您现在所理解的那样,代码根据文本框中的输入过滤列表框,这就像一个魅力顺便说一句。

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

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

非常感谢。

4

2 回答 2

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会修改枚举,导致抛出异常。可能有更简单的方法,但这应该会让你朝着正确的方向前进。

于 2009-04-08T15:46:24.080 回答
0

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

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

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

于 2014-08-01T16:42:52.693 回答