TOC

This article has been localized into Ukrainian by the community.

Команди:

Використання WPF команд

В попередніх статтях ми розказували теорію про команди та про те, як вони працюють. У цій статті ми поглянемо на те, як використовувати команди, присвоюючи їх елементам користувацького інтерфейсу та створюючи прив'язки команд для того, щоб зв'язати їх до купи.

Почнімо з дуже простого прикладу:

<Window x:Class="WpfTutorialSamples.Commands.UsingCommandsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="UsingCommandsSample" Height="100" Width="200">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.New" Executed="NewCommand_Executed" CanExecute="NewCommand_CanExecute" />
    </Window.CommandBindings>

    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button Command="ApplicationCommands.New">New</Button>
    </StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;

namespace WpfTutorialSamples.Commands
{
	public partial class UsingCommandsSample : Window
	{
		public UsingCommandsSample()
		{
			InitializeComponent();
		}

		private void NewCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = true;
		}

		private void NewCommand_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			MessageBox.Show("The New command was invoked");
		}
	}
}

Ми визначаємо прив'язки команд вікна, додаючи їх до колекції CommandBindings. Ми визначаємо коману, яку хочемо використати (команду "Створити новий..." (New) з категорії команд застосунку (ApplicationCommands)) та два обробники подій. Графічний інтерфейс складається з однієї кнопки, до якої ми прикріплили команду, використавши властивість Command.

В C# коді ми обробили дві події. Обробник CanExecute, який WPF викличе, щоб дізнатися доступність поточної команди. У прикладі цей обробник дуже простий, оскільки нам потрібно, щоб команда була доступна постійно. Для цього ми задаємо властивості CanExecute значення true.

Та обробник Executed, який просто показує вікно для повідомлень при виклику команди. Якщо ви запустите зразок та натиснете кнопку, то побачите це повідомлення. Слід зауважити, що ця команда має комбінацію клавіш за умовчуванням, замість натискання кнопки ви можете ввести Ctrl+N на клавіатурі.

Використання методу CanExecute

У першому прикладі ми реалізували подію CanExecute, просто повертаючи значення true, зробивши кнопку постійно доступною. Проте для багатьох випадків це погане рішення, зазвичай, вам потрібно, щоб кнопка була ввімкнутою чи вимкнутою, в залежності від стану певного об'єкта у вашому застосунку.

Ось дуже простий приклад, який полягає у перемиканні стану кнопок "Копіювати" та "Вирізати", в залежності від того, чи виділено тексту, та стану кнопки "Вставити", в залежності від вмісту буферу обміну:

<Window x:Class="WpfTutorialSamples.Commands.CommandCanExecuteSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CommandCanExecuteSample" Height="200" Width="250">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Cut" CanExecute="CutCommand_CanExecute" Executed="CutCommand_Executed" />
        <CommandBinding Command="ApplicationCommands.Paste" CanExecute="PasteCommand_CanExecute" Executed="PasteCommand_Executed" />
    </Window.CommandBindings>
    <DockPanel>
        <WrapPanel DockPanel.Dock="Top" Margin="3">
            <Button Command="ApplicationCommands.Cut" Width="60">_Cut</Button>
            <Button Command="ApplicationCommands.Paste" Width="60" Margin="3,0">_Paste</Button>
        </WrapPanel>
        <TextBox AcceptsReturn="True" Name="txtEditor" />
    </DockPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;

namespace WpfTutorialSamples.Commands
{
	public partial class CommandCanExecuteSample : Window
	{
		public CommandCanExecuteSample()
		{
			InitializeComponent();
		}

		private void CutCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = (txtEditor != null) && (txtEditor.SelectionLength > 0);
		}

		private void CutCommand_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			txtEditor.Cut();
		}

		private void PasteCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = Clipboard.ContainsText();
		}

		private void PasteCommand_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			txtEditor.Paste();
		}
	}
}

Цей простий інтефрейс містить дві кнопки та TextBox. Перша призначена для того, щоб вирізати текст в буфер обміну, а друга для того, щоб вставляти текст з нього.

В C# коді містяться по дві події для кожної кнопки. Та, що виконує дію, (її ім'я закінчується на "_Executed") та подія CanExecute. У кожній з них я застосував певну логіку, що визначає можливість виконання дії, та встановив цю можливість в якості значення властивості CanExecute.

Дуже зручно те, що вам не потрібно викликати ці методи, щоб оновити кнопки. WPF робить це автоматично, тож ваші кнопки постійно будуть оновлені.

Поведінка команд за умовчуванням та CommandTarget

Як видно з попереднього прикладу, обробка набору команд може зайняти досить багато коду, при тому, що вона містить стандартизовану логіку. Саме тому команда WPF вирішила взяти частину цієї роботи на себе. Насправді можна було обійтися без цього коду, адже WPF TextBox автоматично обробляє такі команди, як "Вирізати" (Cut), "Копіювати" (Copy), "Вставити" (Paste), "Відмінити останню дію" (Undo) та "Повторити останню дію" (Redo).

WPF обробляє для вас події Executed та CanExecute. Ви можете перевизначити їх, адже вони просто роблять те саме, що ми робили у попередньому прикладі. Однак, якщо вам просто потрібна базова поведінка, то ви можете дозволити WPF зробити все за вас. Погляньте наскільки спростився цей приклад:

<Window x:Class="WpfTutorialSamples.Commands.CommandsWithCommandTargetSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CommandsWithCommandTargetSample" Height="200" Width="250">
    <DockPanel>
        <WrapPanel DockPanel.Dock="Top" Margin="3">
            <Button Command="ApplicationCommands.Cut" CommandTarget="{Binding ElementName=txtEditor}" Width="60">_Cut</Button>
            <Button Command="ApplicationCommands.Paste" CommandTarget="{Binding ElementName=txtEditor}" Width="60" Margin="3,0">_Paste</Button>
        </WrapPanel>
        <TextBox AcceptsReturn="True" Name="txtEditor" />
    </DockPanel>
</Window>

Не потрібно жодного C# коду - WPF робить все за нас. Але тільки тому що ми використовуємо саме ці команди для саме цього елементу керування.

Зауважче, як я використав властивість CommandTarget, щоб прив'язати команди до елементу TextBox. Це потрібно в цьому конкретному випадку, адже WrapPanel обробляє фокус не так, як наприклад: Toolbar чи Menu, однак при роботі з ним також є сенс у тому, щоб надавати командам цілі.

Підсумок

Працювати з командами досить просто, хоч це й вимагає трохи додаткової розмітки та коду. Однак це дуже корисне рішення, якщо вам потрібно викликати певні дії різними способами, або, якщо ви хочете використати вбудовані у WPF команди.

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!