ComboBox

Последнее обновление: 29.01.2023

Класс ComboBox представляет выпадающий список. Например, определим элемент ComboBox в xaml:

<Window x:Class="MetanitApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="METANIT.COM" Height="200" Width="300">
    <StackPanel>
        <ComboBox>
            <sys:String>Tom</sys:String>
            <sys:String>Bob</sys:String>
            <sys:String>Sam</sys:String>
            <sys:String>Alice</sys:String>
        </ComboBox>
    </StackPanel>
</Window>

Здесь в качестве элементов выпадающего списка используются строки. И после запуска программы мы сможем выбрать один из четырех элементов:

ComboBox в WPF и C#

В реальности в качестве элементов могут выступать любые объекты, например, элементы TextBlock:

<ComboBox>
    <TextBlock>Tom</TextBlock>
    <TextBlock>Bob</TextBlock>
    <TextBlock>Sam</TextBlock>
    <TextBlock>Alice</TextBlock>
</ComboBox>

Результат будет тот же самый, что и в предыдущем случае.

Однако также в WPF предоставляет для ComboBoxe специальный тип - ComboBoxItem. ComboBoxItem представляет элемент управления содержимым, в который через свойство Content мы можем поместить другие элементы. Например:

<Window x:Class="MetanitApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="METANIT.COM" Height="200" Width="300">
    <StackPanel>
        <ComboBox>
            <ComboBoxItem>
                <StackPanel>
                    <TextBlock FontSize="16">Tom</TextBlock>
                    <TextBlock>Microsoft</TextBlock>
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel>
                    <TextBlock FontSize="16">Bob</TextBlock>
                    <TextBlock>Google</TextBlock>
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel>
                    <TextBlock FontSize="16">Sam</TextBlock>
                    <TextBlock>JetBrains</TextBlock>
                </StackPanel>
            </ComboBoxItem>
        </ComboBox>
    </StackPanel>
</Window>
Элемент ComboBox и создание выпадающих списков в WPF и C#

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

Как и другие элементы управления списками, ComboBox можно отображать объекты пользовательсих классов. Например, определим пустой ComboBox:

<Window x:Class="MetanitApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        mc:Ignorable="d"
        Title="METANIT.COM" Height="200" Width="300">
    <StackPanel>
        <ComboBox x:Name="peopleComboBox" />
    </StackPanel>
</Window>

В файле связанного кода C# определим класс Person, который представляет данные, и добавим в список несколько объектов этого класса:

using System.Windows;

namespace MetanitApp;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        peopleComboBox.ItemsSource = new Person[]
        {
            new Person { Name = "Tom", Company = "Microsoft" },
            new Person { Name = "Bob", Company = "Google" },
            new Person { Name = "Sam", Company = "JetBrains" }
        };
    }
}
public class Person
{
    public string Name { get; set; } = "";
    public string Company { get; set; } = "";
    public override string ToString() => $"{Name} ({Company})";
} 
Отображение сложных объектов в ComboBox в WPF и C#

По умолчанию ComboBox выводит строковое представление объекта. Если необходимо отображать значение определенного свойства, применяется свойство DisplayMemberPath, например, выведем значение свойства Name:

<ComboBox x:Name="peopleComboBox" DisplayMemberPath="Name" />

Событие SelectionChanged и обработка выбора объекта

Обрабатывая событие SelectionChanged, мы можем динамически получать выделенный элемент. Для управления выбранными объектами класс ComboBox предоставляет следующие свойства:

  • SelectedItem: выбранный объект списка

  • SelectedValue: выбранное значение

  • SelectedIndex: индекс выбранного объекта в списке

Определим в xaml следующий интерфейс:

<Window x:Class="MetanitApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="METANIT.COM" Height="200" Width="300">
    <StackPanel>
        <TextBlock x:Name="selectedLabel" FontSize="18" />
        <ComboBox x:Name="peopleComboBox" SelectionChanged="peopleComboBox_SelectionChanged" />
    </StackPanel>
</Window>

Здесь для события SelectionChanged установлен обработчик "peopleComboBox_SelectionChanged", а для вывода выбранного объекта определен элемент TextBlock.

В коде C# определим обработчик события:

using System.Windows;
using System.Windows.Controls;

namespace MetanitApp;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        peopleComboBox.ItemsSource = new Person[]
        {
            new Person { Name = "Tom", Company = "Microsoft" },
            new Person { Name = "Bob", Company = "Google" },
            new Person { Name = "Sam", Company = "JetBrains" }
        }; 
        peopleComboBox.SelectedIndex = 1;   // по умолчанию будет выбран второй элемент
    }

    private void peopleComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if(peopleComboBox.SelectedItem is Person person) 
        {
            selectedLabel.Text = person.Name;
        }
    }
}
public class Person
{
    public string Name { get; set; } = "";
    public string Company { get; set; } = "";
    public override string ToString() => $"{Name} ({Company})";
} 

Поскольку здесь элементами списка являются объекты Person, то выбранный объект мы можем привести к типу Person

if(peopleComboBox.SelectedItem is Person person)

И вывести в текстовую метку значение свойства Name:

Обработка выбора элемента и событие SelectionChanged в WPF и C#

Также мы могли бы использовать свойство SelectedValue, которое представляет выбранное значение. Для его использования определим следующий код xaml:

<Window x:Class="MetanitApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="METANIT.COM" Height="200" Width="300">
    <StackPanel>
        <TextBlock x:Name="selectedPerson" FontSize="18" />
        <ComboBox x:Name="peopleComboBox" SelectedValuePath="Name" 
                  SelectionChanged="peopleComboBox_SelectionChanged" />
    </StackPanel>
</Window>

Обратите внимание на свойство SelectedValuePath="Name" - здесь мы указываем, что свойство "Name" будет выступать в качестве свойства значения.

Для обработки события выбора элемента определим следующий код C#:

using System.Windows;
using System.Windows.Controls;

namespace MetanitApp;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        peopleComboBox.ItemsSource = new Person[]
        {
            new Person { Name = "Tom", Company = "Microsoft" },
            new Person { Name = "Bob", Company = "Google" },
            new Person { Name = "Sam", Company = "JetBrains" }
        };
        peopleComboBox.SelectedIndex = 1;   // по умолчанию будет выбран второй элемент
    }

    private void peopleComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if(peopleComboBox.SelectedValue is { }) // если не равно null
        {
            selectedPerson.Text = peopleComboBox.SelectedValue.ToString();
        }   
        // или так
        // selectedPerson.Text = peopleComboBox.SelectedValue?.ToString();
    }
}
public class Person
{
    public string Name { get; set; } = "";
    public string Company { get; set; } = "";
    public override string ToString() => $"{Name} ({Company})";
} 

Здесь проверяем, не равно ли peopleComboBox.SelectedValue null (хотя в примере выше это не имеет смысла, поскольку это свойство представляет строку), и выводим значение этого свойства в текстовый блок. Результат будет аналогичен предыдущему.

Свойства

Установка свойства IsEditable="True" позволяет вводить в поле списка начальные символы, а затем функция автозаполнения подставит подходящий результат. По умолчанию свойство имеет значение False.

Это свойство работает в комбинации со свойством IsReadOnly: оно указывает, является поле ввода доступным только для чтения. По умолчанию имеет значение False, поэтому если IsEditable="True", то мы можем вводить туда произвольный текст.

Еще одно свойство StaysOpenOnEdit при установке в True позволяет сделать список раскрытым на время ввода значений в поле ввода.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850