WPF - Реализация алгоритмов поиска

Поиск - один из самых важных алгоритмов программы, без которого на сегодняшний день не обходиться не одна информационная система, особенно работающая с большими объёмами данных.

В этой статье я бы хотел рассказать и показать как можно реализовать алгоритмы поиска и фильтрации в приложении написанном на WPF C#.

Что такое WPF?

Windows Presentation Foundation — один из компонентов ядра .NET Framework, который позволяет разработчикам создавать богатые, различные Windows приложения.

Логотип WPF

Создаём интерфейс для алгоритма поиска и фильтрации.

Самое первое что нужно сделать, это запустить Microsoft Visual Studio. А далее создать проект выбрав пункт "Приложение WPF" - Visual C#;

Создание нового проекта WPF - Visual C#

Следующим шагом настроим минимальные значения высоты и ширины окна, а также зададим значения по умолчанию.

Настройка максимального значения высоты и ширины программы, а также значения по умолчанию.

Реализовываем следующий интерфейс используя такие элементы как: Label, ComboBox, TextBox,  ListView, Button. Как пользоваться ListView можно прочитать в этой статье.

Интерфейс программы для реализации алгоритма поиска.

Далее, присвоим атрибут DisplayMemberBinding для тегов GridViewColumn, дав наименования в соответствии с рисунком ниже.

Атрибут DisplayMemberBinding для тегов GridViewColumn

Для элемента ComboBox зададим атрибут x:Name="genderFilter", а для TextBox атрибут x:Name="nameFilter", для ListView – x:Name="userList". Так же для элемента Button создадим обработчик события на активность Click.

Обработчик события на активность Click

XAML - разметка, полный код:

<Window x:Class="SearchAlgorithm.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Реализация алгоритмов поиска. " Height="450" Width="800" MinWidth="800" MinHeight="400">
    <Grid>
        <Label Content="Фильтровать:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
        <Label Content="По полу:" HorizontalAlignment="Left" Margin="10,41,0,0" VerticalAlignment="Top"/>
        <ComboBox x:Name="genderFilter" HorizontalAlignment="Left" Margin="73,45,0,0" VerticalAlignment="Top" Width="150">
            <TextBlock>Мужской</TextBlock>
            <TextBlock>Женский</TextBlock>
        </ComboBox>
        <Label Content="Поиск:" HorizontalAlignment="Left" Margin="228,41,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="nameFilter" Height="23" Margin="280,45,165,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top"/>
        <Button Click="ActiveFilter" Content="Применить фильтр" HorizontalAlignment="Right" Margin="0,45,10,0" VerticalAlignment="Top" Width="150"/>
        <ListView x:Name="userList" Margin="10,73,10,10">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Фамилия и инициалы" Width="150" DisplayMemberBinding="{Binding name}"/>
                    <GridViewColumn Header="Дата рождения" Width="120" DisplayMemberBinding="{Binding dataOfBirth}"/>
                    <GridViewColumn Header="Возраст" Width="100" DisplayMemberBinding="{Binding age}"/>
                    <GridViewColumn Header="Пол" Width="100" DisplayMemberBinding="{Binding gender}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

Пишем алгоритм поиска и фильтрации.

В первую очередь создадим класс объектов, хранящий в себе такие переменные как name, dataOfBirth, age, gender и реализуем функцию, отвечающую за заполнение этих данных:

public class User
{
    public string name { get; set; }
    public string dataOfBirth { get; set; }
    public string age { get; set; }
    public string gender { get; set; }

    public User(string _name, string _dataOfBirth, string _age, string _gender)
    {
        this.name = _name;
        this.dataOfBirth = _dataOfBirth;
        this.age = _age;
        this.gender = _gender;
     }
}

Сразу же создадим массив этого класса, предполагая что у нас будет несколько значений.

public List<User> user = new List<User>();

Далее, необходимо создать функцию LoadUser, принимающую в качестве аргумента массив класса User и вызвать её после инициализации компонентов, отправив созданный массив класса user.

public void LoadUser(List<User> _user)
{
    userList.Items.Clear(); // очищаем лист с элементами

    for (int i = 0; i < _user.Count; i++) // перебираем элементы
    {
        userList.Items.Add(_user[i]); // добавляем элементы в ListBox
    }
}

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

Вызовем эту функцию в после инициализации компонентов формы, чтобы сразу же отобразить имеющиеся данные. Стоп! А какие данные мы собрались отображать? Которых нет?

Добавим эти самые данные.

Перед выполнением функции пропишем добавление данных:

public MainWindow()
{
    InitializeComponent();

    // Добавляем данные
    user.Add(new User("Каримов А.О.", "27.04.1996", "23", "M"));
    user.Add(new User("Шишкин К.А.", "25.02.1998", "21", "M"));
    user.Add(new User("Кучукбаева Л.А.", "18.02.1999", "20", "F"));
    user.Add(new User("Белов А.В.", "25.02.1997", "22", "M"));
    user.Add(new User("Хоробрых Г.Д.", "25.02.1996", "23", "M"));
    user.Add(new User("Юкович Н.Т.", "25.02.1995", "22", "M"));
    user.Add(new User("Власов А.А.", "25.02.1994", "25", "M"));
    user.Add(new User("Теплоухов Н.С.", "25.02.1993", "26", "M"));
    LoadUser(user); // выводим данные на экран
}

Запустив программу, можно увидеть что все данные благополучно вывелись на экран программы:

Результат выполнения программы реализации алгоритма поиска

Чтож, добавим в элемент ComboBox, два TextBlock’a, задав значения Мужской и Женский на XAML-разметке.

Два TextBlock в элементе ComboBox

Следующим шагом реализовываем функцию фильтрации по признаку пола: для этого необходимо создать новый массив класса User. А далее в зависимости от выбранного значения произвести поиск в массиве с определённым условием:

private void ActiveFilter(object sender, RoutedEventArgs e)
{
    List<User> newUsers = new List<User>();
    newUsers = user;

    if (genderFilter.SelectedIndex == 0)
        newUsers = user.FindAll(x => x.gender == "M");
    else
        newUsers = user.FindAll(x => x.gender == "F");

    LoadUser(newUsers);
}

Функция работает следующим образом: если у нас выбран мужской пол, то из всего массива класса будут отобраны только те элементы, которые в качестве значения gender принимают "М". Если же пол женский - соответственно будут выбраны только записи с женским полом. Если же не выбрано ни чего, то будут отображены все записи.

После сортировки по половому фильтру необходимо добавить алгоритм кода, позволяющий производить точное совпадение, со строкой находящейся в TextBox:

newUsers = newUsers.FindAll(x => x.name.Contains(nameFilter.Text));

Contains - этот метод позволяет производить совпадение в записи числа, с каким-то конкретным значением.

Если запустить программу то, можно заметить, что фильтр по половому признаку работает. Точно также как и поиск по совпадениям.

3.13/5 (8)

Оцените