Практическое занятие № 20
Тема: Привязка MultiBinding в WPF
Цель работы: получить практический опыт в привязке данных в WPF.
Приобретаемые умения и навыки: умение работать с привязкой MultiBinding в WPF.
Норма времени: 2 часа.
Оборудование: Компьютер с установленным программным обеспечением и подключенный к Internet.
Методические указания по выполнению практической работы
Существуют 3 вида привязок: Binding, Priority Binding и MultiBinding.
Мы рассмотрим MultiBinding.
Свойство MultiBinding позволяет привязать к одному свойству несколько других привязок, например:
MultiBinding Converter="{StaticResource JoinStringConverter}" ConverterParameter=" "
Binding Path="LastName" /
MultiBinding
MultiBinding очень похож на Binding, но позволяет использовать несколько источников для одной и той же цели, так что цель изменяется всякий раз, когда каждый из исходных значений изменяется. Эти несколько источников объединяются в одно значение с помощью преобразователя нескольких значений (который реализует IMultiValueConverterинтерфейс).
Например, цвет может быть вычислен из красного, синего и зеленого значений, которые могут быть значениями из тех же или разных объектов источника привязки. Когда значение перемещается из целевого объекта в источники, значение целевого свойства преобразуется в набор значений, которые передаются обратно в привязки.
Точно так же как Binding, MultiBinding может работать в обоих направлениях (в TwoWay режиме) и от цели к нескольким источникам (в OneWayToSource режиме), но эти два режима редко используются, потому что, как правило, нельзя однозначно воссоздать несколько источников из одной цели.
Converter, же, в свою очередь получает или задает преобразователь, который должен использоваться для преобразования исходных значений в целевое значение или из целевого значения.
Он может принимать такие значения, как:
- StringFormat
- JoinStringConverter
MultiBinding в настоящее время поддерживает только объекты типа Binding.
Яркий пример MultiBinding’а:
У нас имеется список людей Human. Перед нами стоит задача, собрать фамилию, имя и отчество в один элемент TextBlock.
Решение этой задачи представлено ниже.
class Human
{
public string Name { get; set; }
public string Surname { get; set; }
public string Patronymic { get; set; }
}
Листинг 1 – Класс Human
Листинг 2 – Разметка MainWindow.xaml
public MainWindow()
{
InitializeComponent();
Human human = new Human();
human.Name = "Иван";
human.Surname = "Иванов";
human.Patronymic = "Иванович";
List _humans = new List();
for (int i = 0; i
{
_humans.Add(human);
}
lvHumans.ItemsSource = _humans;
}
Листинг 3 – Код MainWindow.xaml.cs
Рис. 1 – Результат
Возьмем пример посложнее.
Есть задача, чтобы во время написания фамилии и имени в поле для ввода текста, этот тест сразу же появлялся в другом поле для ввода.
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:local="clr-namespace:BindingExample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
Листинг 4 – Разметка окна
Рис. 2 – Внешний вид разметки
public class NameConvertor : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return String.Concat(values[0], ",", values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
return (value as string).Split(',');
}
}
///
/// Логика взаимодействия для MainWindow.xaml
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
Листинг 5 – Код программы
Рис. 3 – Результат
Как вы можете видеть, во втором примере мы реализуем интерфейс IMultiValueConverter. А в нем мы связываем реализуем методы Convert и ConvertBack. Таким образом мы связываем преобразователь и MultiBinding.
Пример 3:
Создадим MultiBinding в элементе ComboBox.
public class Warehouse
{
public string Town { get; set; }
public string Address { get; set; }
public string Name { get; set; }
}
Листинг 6 – Класс
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:local="clr-namespace:MultiBExample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
Листинг 7 – Код разметки
public MainWindow()
{
InitializeComponent();
Warehouse warehouse = new Warehouse();
warehouse.Name = "Склад 4";
warehouse.Town = "Москва";
warehouse.Address = "ул. Центральная 5к3";
Warehouse warehouse2 = new Warehouse();
warehouse2.Name = "Склад 5";
warehouse2.Town = "Тула";
warehouse2.Address = "ул. Карла Маркса 50";
List _warehouses = new List();
_warehouses.Add(warehouse);
_warehouses.Add(warehouse2);
cbWarehouses.ItemsSource = _warehouses;
}
Листинг 8 – Код программы
Рис. 4 – Результат
Пример 4:
Возьмем 3 элемента – ComboBox, TextBox и Button. Если элемент в ComboBox выбран и что-то написано в TextBox, то кнопка будет активирована.
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:local="clr-namespace:MultiBExample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
Листинг 9 – Разметка
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class FormFilledMultiConverter : IMultiValueConverter
{
#region IMultiValueConverter Members
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
for (int i = 0; i
if (values[i] == null)
return false;
string name = values[0].ToString();
int selectedIndex = System.Convert.ToInt32(values[1]);
//if some text was entered for then name AND a letter was chosen from the combobox, return true, else return false.
return (name.Length 0 && selectedIndex != -1) ? true : false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
Листинг 10 – Код программы
Рис. 5 – Результат
Рис. 6 – Результат
Контрольные вопросы:
Какие виды привязок существуют в WPF?
Охарактеризовать привязку MultiBinding в WPF?