Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
course_(Windows&Web).docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
4.68 Mб
Скачать

Команды и привязка к данным

Одна из наиболее интересных и мощных возможностей команд – это интеграция с привязкой к данным. Поскольку у элементов есть свойства Command и CommandParameter, их можно привязать к данным. А, значит, именно от данных будет зависеть происходящее в программе.

Чтобы понять, как все стыкуется, напишем приложение, которое выводит список всех файлов на диске c:\. Определим простое диалоговое окно со списковым полем и шаблон данных для отображения имени одного файла:

<Window x:Class=’EssentialWPF.DataAndCommands’ xmlns=’http://schemas.microsoft.com/winfx/2006/xaml/presentation’ xmlns:x=’http://schemas.microsoft.com/winfx/2006/xaml’ Title=’Data and Commands’> <ListBox Margin=’2’ Name=’_files’> <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text=’{Binding Path=Name}’ /> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Window>

Затем запишем в свойство ItemsSource список файлов:

public partial class DataAndCommands: Window { public DataAndCommands() { InitializeComponent(); FileInfo[] fileList = new DirectoryInfo(«c:\\»).GetFiles(«*.*»); _files.ItemsSource = fileList; } }

Теперь хотелось бы добавить кнопку для вывода содержимого файла. Но нам не нужно, чтобы запускались произвольные приложения, поэтому следует поставить фильтр на те типы файлов, которые мы согласны загружать. У нас будет две команды: Open и Blocked.

public partial class DataAndCommands: Window { public static readonly RoutedCommand OpenCommand = new RoutedCommand(«Open», typeof(DataAndCommands)); public static readonly RoutedCommand BlockedCommand = new RoutedCommand(«Blocked», typeof(DataAndCommands)); ... }

Понадобятся также обработчики этих команд:

public partial class DataAndCommands: Window { public DataAndCommands() { InitializeComponent(); CommandBindings.Add(new CommandBinding(OpenCommand, delegate (object sender, ExecutedRoutedEventArgs e) {Process.Start(«notepad.exe», (string)e.Parameter);})); CommandBindings.Add(new CommandBinding(BlockedCommand, delegate (object sender, ExecutedRoutedEventArgs e) {MessageBox.Show((string)e.Parameter, «Blocked»);})); } }

Определив обе команды, мы можем модифицировать шаблон данных, включив в него кнопку. Можно воспользоваться привязкой к данным для задания параметра команды (имени файла). Что касается самой команды, то, поскольку мы хотим, чтобы для одних элементов списка вызывалась команда OpenCommand, а для других – BlockedCommand, то реализуем интерфейс IValueConverter для перехода от имени файла к объекту ICommand:

<DataTemplate> <WrapPanel> <TextBlock Text=’{Binding Path=Name}’ /> <Button CommandParameter=’{Binding Path=FullName}’> <Button.Command> <Binding> <Binding.Converter> <l:FileToCommandConverter /> </Binding.Converter> </Binding> </Button.Command> Show </Button> </WrapPanel> </DataTemplate>

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

public class FileToCommandConverter: IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { string ext = ((FileInfo)value).Extension.ToLowerInvariant(); if (ext == «.txt») { return DataAndCommands.OpenCommand; } return DataAndCommands.BlockedCommand; } ... }

Запустив эту программу, мы убедимся, что можно просматривать содержимое только текстовых файлов. Этот пример слишком прост; того же самого можно было бы достичь с помощью метода CanExecute с последующим блокированием выполнения команды для «плохих» файлов. Но важно подчеркнуть, что мы могли бы вернуть любую команду. Таким образом, поведение элемента определяется данными.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]