WPF AutoCompleteBox动态排序 [英] WPF AutoCompleteBox dynamic sorting

查看:256
本文介绍了WPF AutoCompleteBox动态排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用WPF AutoCompleteBox,我有它的工作很好,但有一件事我会做的是那种每个字母后飞建议名单输入到文本框小学。有谁知道如何做到这一点?我试着用的ICollectionView属性与默认视图逻辑和添加SortDescriptions,但它似乎不相建议列表。为了确保我的集合视图分选工作,我把一个正常的ListBox控件,并在同一窗口上的AutoCompleteBox控制和约束两个控件到同一个观察的集合使用相同的集合视图和正常的ListBox控件显示排序项正确使用SortDescriptions ,但AutoCompleteBox列表没有排序的项目。它有他们在他们被加入到集合中的顺序

I am using the WPF AutoCompleteBox and I have it working great, but one thing I would like to do is sort the suggestion list on the fly after each letter is entered into the primary TextBox. Does anyone know how to do this? I tried using an ICollectionView property with the DefaultView logic and adding SortDescriptions but it doesn't seem to phase the suggestion list. To make sure my collection view sorting was working I put a normal ListBox control and an AutoCompleteBox control on the same window and bound both controls to the same observable collection with the same collection view and the normal ListBox control showed the items sorted correctly using the SortDescriptions, but the AutoCompleteBox list didn't have the items sorted. It had them in the order they were added to the collection.

的思考?建议?有没有人这样做呢?

Thoughts? Suggestions? Has anyone done this?

推荐答案

这是我结束了,Sevenate的回答略有调整,所以如果你想给予好评,这样对他的职务。

This is what I ended up with, a slight adaptation of Sevenate's answer, so if you wanted to upvote, do that to his post.

我用了一个子类(我有 AutoCompleteBox 子类已因其他原因),这让我创建一​​个包装依赖属性得到只读 SEARCHTEXT (=什么通过键盘输入的用户)的视图模型 - 而不是一个混合的行为,这是一种非常有效的方式,太

I used a subclass (I had the AutoCompleteBox subclassed already for other reasons), which allows me to create a wrapper dependency property to get the readonly SearchText (=what the user entered via keyboard) to the ViewModel - instead of a blend behavior, which is a perfectly valid way, too.

而问题的关键是,你应该只在SEARCHTEXT的变化应用动态排序,不是文本(=所显示的 AutoCompleteBox ,也将如建议在下拉列表中选择的变化)。 Sevenate的方式来提高只读的ItemsSource的PropertyChanged事件( ItemsSorted )是应用排序一个非常干净的方式。

The crux of the matter is that you should only apply the dynamic sorting upon changes of SearchText, not Text (=what is displayed in the AutoCompleteBox, will also change if a suggestion is selected in the dropdown). Sevenate's way to raise the PropertyChanged event of the readonly ItemsSource (ItemsSorted) is a nice and clean way to apply the sorting.

视图模型:

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

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

public class AutoCompleteBoxDynamicSortingVM : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private readonly ObservableCollection<Item> source;

    public AutoCompleteBoxDynamicSortingVM()
    {
        source = new ObservableCollection<Item>
                     {
                         new Item {Name = "111111111 Test abb - (1)"},
                         new Item {Name = "22222 Test - (2)"},
                         new Item {Name = "333 Test - (3)"},
                         new Item {Name = "44444 Test abc - (4)"},
                         new Item {Name = "555555 Test cde - (5)"},
                         new Item {Name = "66 Test - bbcd (6)"},
                         new Item {Name = "7 Test - cd (7)"},
                         new Item {Name = "Test - ab (8)"},
                     };
    }

    public IEnumerable<Item> ItemsSorted
    {
        get
        {
            return string.IsNullOrEmpty(Text) ? (IEnumerable<Item>)source :
                    source.OrderBy(item => item.Name.IndexOf(Text, StringComparison.OrdinalIgnoreCase));
        }
    }

    public Item Selected { get; set; }

    // Text that is shown in AutoCompleteBox
    private string text;
    public string Text
    {
        get { return text; }
        set { text = value; OnPropertyChanged("Text"); }
    }

    // Text that was entered by user (cannot be changed from viewmodel)
    private string searchText;
    public string SearchText
    {
        get { return searchText; }
        set
        {
            searchText = value;
            OnPropertyChanged("SearchText");
            OnPropertyChanged("ItemsSorted");
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

AutoCompleteBox的子类:

Subclass of AutoCompleteBox:

public class MyAutoCompleteBox : AutoCompleteBox
{
    /// <summary>
    /// Bindable property that encapsulates the readonly property SearchText.
    /// When the viewmodel tries to set SearchText by way of EnteredText, it will fail without an exception.
    /// </summary>
    public string EnteredText
    {
        get { return (string)GetValue(EnteredTextProperty); }
        set { SetValue(EnteredTextProperty, value); } 
    }
    public static readonly DependencyProperty EnteredTextProperty = DependencyProperty.Register("EnteredText", typeof(string), typeof(MyAutoCompleteBox), new PropertyMetadata(null));


    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        // synchronize SearchText and EnteredText (only one-way)
        if (e.Property == AutoCompleteBox.SearchTextProperty && this.EnteredText != this.SearchText)
            EnteredText = SearchText;

        base.OnPropertyChanged(e);
    }
}

XAML中:

<UserControl x:Class="WpfApplication1.Controls.AutoCompleteBoxDynamicSorting"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:myctrls="clr-namespace:WpfApplication1.Controls"
        xmlns:models="clr-namespace:WpfApplication1.ViewModels"
        Height="350" Width="525"
        DataContext="{DynamicResource viewModel}">

    <UserControl.Resources>

        <models:AutoCompleteBoxDynamicSortingVM x:Key="viewModel" />

        <DataTemplate DataType="{x:Type models:Item}">
            <TextBlock Text="{Binding Path=Name}" />
        </DataTemplate>

    </UserControl.Resources>

    <Grid>
        <myctrls:MyAutoCompleteBox
            ItemsSource="{Binding ItemsSorted}"
            Text="{Binding Text, Mode=TwoWay}"
            EnteredText="{Binding SearchText, Mode=OneWayToSource}"
            FilterMode="ContainsOrdinal"
            VerticalAlignment="Top" Margin="5" />
    </Grid>
</UserControl>

这篇关于WPF AutoCompleteBox动态排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆