1

Тема: Silverlight ListBox с текстовым поиском

Silverlight ListBox с текстовым поиском

Мой Silverlight контрол TextSearchListBox наследуется от ListBox и предоставляет возможность текстового поиска, которую многие ожидают увидеть в приложениях. Взаимодействие с таким списком намного лучше, чем со стандартным ListBox, и мне не составило большого труда создать этот контрол сегодня вечером.

Я приложил к статье проект целиком со всеми исходниками, и надеюсь, что этот контрол пригодится в ваших приложениях в той или иной форме.

Thumbs up Thumbs down

2

Re: Silverlight ListBox с текстовым поиском

Что такое текстовый поиск?

Когда ваш список находится в фокусе, и вы печатаете какой-либо символ, то в списке автоматически выбирается элемент, первый символ которого совпадает с тем, который вы напечатали. Например, в приложении примера, я кликнул по списку, чтобы он получил фокус ввода, и затем напечатал символ ‘c’:

http://silverlight.su/data/themes/controls/ListBoxes/TextSearchListBox/_1.png

Нажат символ «с» -- выбран пункт Charlotte


Если вы просматриваете список с тысячью пунктами, например музыкальный плейлист, такая функция здорово сэкономит время и нервы. Вы можете продолжать быстро печатать искомое слово до конца и даже использовать клавишу Backspace, если ошиблись.

Если я быстро напечатаю символ «о» сразу же после первого символа, тогда выделится город Colubus:

http://silverlight.su/data/themes/controls/ListBoxes/TextSearchListBox/_2.png

Нажмите «с», а затем без задержки «о», будет выбран Columbus


Логика поиска контрола также умеет обрабатывать повторы нажатий для перемещения вниз по списку. Например, если вы быстро напечатаете символ «d» 5 раз подряд, тогда выделение переместится с пункта Dallas на Detroit:

http://silverlight.su/data/themes/controls/ListBoxes/TextSearchListBox/_3.png

Символ «d» нажат 5 раз подряд - выделение переместилось сразу на 5-й элемент, начинающийся с «d».


Sergey пишет:

Если добавить в список строку 'Ddd', то перемещение дойдет только до этой строки, сколько бы раз вы не жали «d».

Это отличная функция и относительно проста в реализации, особенно с учетом сходства с обычным контролом автозаполнения.

Честно говоря, до того, как я пришел в Microsoft несколько лет назад, я и не думал, что стандартный список может иметь такую полезную функцию. Это один их тех скрытых драгоценных камней, который я использовал довольно часто с той поры, как узнал об этой возможности.

Thumbs up Thumbs down

3

Re: Silverlight ListBox с текстовым поиском

Как определяется строковое значение элемента списка

Строковое значение извлекается совсем не так, как в WPF. Поскольку ListBox может содержать в качестве элемента списка любой контрол (не обязательно строку), в Silverlight не существует простого способа узнать, какое именно строковое значение контрола является ключевым для поиска, и мне не хотелось загрязнять пример какими-либо обязательными требованиями.

В данном примере я прибег к очень простой логике: оператор ToString() используется для получения строкового значение любого элемента списка.

Так что если в качестве элементов списка вы используете какой-либо контрол вместо обычной строки, поиск не будет работать корректно – алгоритм поиска будет ориентироваться на строку, которую возвращает ваш объект через метод ToString(). Например, если вы завернете текст в TextBlock, тогда метод ToString() буде возвращать строку «System.Windows.Controls.TextBlock». Чтобы объект возвращал правильную строку, нужно всего лишь перегрузить метод ToString(), а если вы не можете отнаследоваться от данного объекта, придумайте обертку или класс-адаптер.

Если вы уже пользовались контролом AutoCompleteBox из Silverlight Toolkit, то обратите внимание, что мой контрол немного другой. Я хотел предоставить больше удобства для конвертирования элементов списка в строки, поэтому реализовал свойство Converter типа IValueConverter, которое будет использовано перед методом ToString().

Thumbs up Thumbs down

4

Re: Silverlight ListBox с текстовым поиском

Как использовать этот контрол

Просто скачайте исходный код или добавьте файл TextSearchListBox.cs в ваш проект и обновите пространство имен.

Вот XAML из примера:

<UserControl x:Class="YourNamespace.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:YourNamespace"
    Width="315" Height="340">
    <Grid x:Name="LayoutRoot" Margin="5">
        <Border BorderBrush="#11999999" BorderThickness="1" CornerRadius="3">
            <Border BorderBrush="#22999999" BorderThickness="1" CornerRadius="3">
                <Border BorderBrush="#33999999" BorderThickness="1" CornerRadius="3">
                    <local:TextSearchListBox x:Name="listBox1" />
                </Border>
            </Border>
        </Border>
    </Grid>
</UserControl>

И код поддержки этого XAML:

using System.Linq;
using System.Windows.Controls;
using Microsoft.Windows.Controls.Samples;

namespace YourNamespace
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            Loaded += (s, e) => listBox1.ItemsSource = (from n in Airport.SampleAirports orderby n.City select n.City).Distinct();
        }
    }
}

Thumbs up Thumbs down

5

Re: Silverlight ListBox с текстовым поиском

Загрузки

•    Загрузить TextSearchListBoxSample.zip (12 KB)
•    Загрузить TextSearchListBox.cs

Рабочее демо примера (Silverlight 3):


Ищите похожий текстовый контрол? В Silverlight имеется контрол AutoCompleteBox – TextBox с выпадающим списком совпадений.

Thumbs up Thumbs down

6

Re: Silverlight ListBox с текстовым поиском

Замечания по реализации

•    Это простейший пример, поэтому никакие дополнительные зависимые свойства не реализованы.

•    Работает только со стандартными клавиатурами, никакие IME или дополнительные символы не поддерживаются.

•    Любой ListBox теоретически может быть заменен на TextSearchListBox.

•    В данном примере не реализована автоматизация пользовательского интерфейса (automation peer).

•    Хорошим улучшением было бы добавление зависимого свойства IsTextSearchEnabled, чтобы выключать и включать поиск. Пока я основываюсь на том, что вам не понадобится отключать поиск, иначе зачем тогда использовать этот контрол.

•    Поскольку Silverlight не предоставляет аналога события TextInput из WPF, я не могу определять, какие символы были введены. Но мои небольшие тесты показали, что контрол работает хорошо в любом случае.

Sergey пишет:

Это означает, что поиск работает только для латиницы.
Ничего хорошего в этом не нахожу.


Источник: Silverlight ListBox with text searching

Thumbs up Thumbs down