Silverlight: Выпадающий список для TextBox

пятница, 22 апреля 2011, bobasoft

Идею AutoCompleteBehavior взял тут, и подправил/изменил чтобы сделать более MVVM friendly.

Потробнее о Behavior можно почитать тут.

Для проекта нужна дополнительная сборка System.Windows.Interactivity.dll.

solution

В примере есть 3 варианта использования AutoCompleteBehavior.

1. Обычное подключение AutoCompleteBehavior к TextBox:

Для начала, нужно будет добавить обьявление пространств имен в MainPage.xaml

xmlns:local="clr-namespace:Msug.Sl.AutoComplete.Behaviors"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

xaml: (MainPage.xaml)

<TextBox>
    <i:Interaction.Behaviors>
          <local:AutoCompleteBehavior ItemsSource="{Binding ModelItems}" Query="{Binding ModelQuery, Mode=TwoWay}"/>
    </i:Interaction.Behaviors>
</TextBox>

code: (в модели MainPageModel - MainPage.model.cs)

    public string ModelQuery
    {
        get { return _modelQuery; }   
        set
        {
            if ( _modelQuery != value)
            {
                _modelQuery = value;
                OnModelQueryChanged();
                RaisePropertyChanged("ModelQuery");
            }
        }
    }

    public ObservableCollection<string> ModelItems { get; private set; }

    private void OnModelQueryChanged()
    {
        ModelItems.Clear();
        foreach (var item in _msOffice.Where(i => i.Contains(_modelQuery)))
            ModelItems.Add(item);
    }

    private readonly string[] _msOffice = new[]
                                  {
                                      "Microsoft Access", "Microsoft Excel", "Microsoft InfoPath", "Microsoft OneNote", "Microsoft Outlook",
                                      "Microsoft Powerpoint", "Microsoft Project", "Microsoft Publisher", "Microsoft Word"
                                  };

Как оно работает: При изменении текста в TextBox, изменяеться свойство Query в AutoCompleteBehavior, а так как идет обратная связь изменяеться и свойство ModelQuery в модели. При изменении значения ModelQuery, вызываем OnModelQueryChanged, выбираем нужные значения из масива _msOffice и добавляем их в колекцию ModeltItems.

drop down list

2. Изменения стиля списка AutoCompleteBehavior:

Для изменения стиля списка, нужно забиндить свойство ContentTemplate в AutoCompleteBehavior. Но обязательно в DataTemplate должен быть компонент ListBox (неважно, или главным елементом, или дочерным, AutoCompleteBehavior выберет первый который найдет).

    <local:AutoCompleteBehavior.ContentTemplate>
        <DataTemplate>
            ...... 
        </DataTemplate>
    </local:AutoCompleteBehavior.ContentTemplate>

     <TextBox>
            <i:Interaction.Behaviors>
                <local:AutoCompleteBehavior ItemsSource="{Binding ModelItems}" Query="{Binding ModelQuery, Mode=TwoWay}">
                    <local:AutoCompleteBehavior.ContentTemplate>
                        <DataTemplate>
                            <ListBox ItemsSource="{Binding ItemsSource}" MaxHeight="75">
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding}" Foreground="Red" Height="20" Width="270"/>
                                    </DataTemplate>         
                                </ListBox.ItemTemplate>         
                            </ListBox>              
                        </DataTemplate>     
                    </local:AutoCompleteBehavior.ContentTemplate>   
                </local:AutoCompleteBehavior>
            </i:Interaction.Behaviors>
        </TextBox>

3. События и изменение формата выбраного елемента из AutoCompleteBehavior:

Добавим еще один компонент (такойже как и в первом примере), только в этот раз назвем AutoCompleteBehavior именем eventAutoComplete.

       <TextBox Height="25" Margin="10,0,0,0" TextWrapping="Wrap" VerticalAlignment="Center" Width="270">
            <i:Interaction.Behaviors>
                <local:AutoCompleteBehavior x:Name="eventAutoComplete" ItemsSource="{Binding ModelItems}" Query="{Binding ModelQuery, Mode=TwoWay}"/>
            </i:Interaction.Behaviors>
        </TextBox>

Для даного примера нужно писать в code-behind (MainPage.xaml.cs): В AutoCompleteBehavior есть два события:

  • Completing - вызов происходит после того как пользователь начнет вводить текст (с задержкой в 100 милисекунд (задано в коде))
  • Completed - вызываеться после того, как пользователь выбрал определенный елемент в списке и получить его можно через аргумент e.SelectedItem. Также это свойство можно изменять, форматируя вывод в TextBox (поддреживаеться присваивание null)

        eventAutoComplete.Completing += (s, e) =>
                                        {
                                            // сдесь можно отменить выполнение e.Cancel = true
                                            // а также посмотреть что ввел пользователь e.Query
                                        };
        eventAutoComplete.Completed += (s, e) =>
                                       {
                                           e.SelectedItem = "MS Office: " + e.SelectedItem; // в TextBox мы увидим измененный текст
                                       };
    

Структура дерева обьектов в Expression Blend:

blend

Проект можно скачать тут.

Спасибо, критика и предложения приветствуються.

Компании из статьи


Microsoft Украина


Сайт:
http://www.microsoft.com/ukr/ua/

Microsoft Украина Украинское подразделение компании Microsoft.

Ищите нас в интернетах!

Комментарии

Свежие вакансии