Пример пользовательского шаблона команды WPF - PullRequest
36 голосов
/ 12 августа 2008

Я занимался программированием на WPF, и одна вещь, которую я никогда не получал, это шаблон команд. Кажется, что каждый пример для встроенных, редактировать, вырезать, вставить. У кого-нибудь есть пример или предложение наилучшей практики для пользовательских команд?

Ответы [ 4 ]

38 голосов
/ 12 августа 2008

Ах, ха! На вопрос я могу ответить! Во-первых, я должен отметить, что лично мне было проще определять и подключать команды в коде, а не в XAML. Это позволяет мне подключать обработчики команд немного гибче, чем это делает весь подход XAML.

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

public static class CommandBank
{
  /// Command definition for Closing a window
  public static RoutedUICommand CloseWindow { get; private set; }

  /// Static private constructor, sets up all application wide commands.
  static CommandBank()
  {
    CloseWindow = new RoutedUICommand();
    CloseWindow.InputGestures.Add(new KeyGesture(Key.F4, ModifierKeys.Alt));
    // ...
  }

Теперь, поскольку я хотел сохранить весь код вместе, использование подхода только к коду для команд позволяет мне поместить следующие методы в вышеприведенный класс:

/// Closes the window provided as a parameter
public static void CloseWindowExecute(object sender, ExecutedRoutedEventArgs e)
{
  ((Window)e.Parameter).Close();
}

/// Allows a Command to execute if the CommandParameter is not a null value
public static void CanExecuteIfParameterIsNotNull(object sender, CanExecuteRoutedEventArgs e)
{
  e.CanExecute = e.Parameter != null;
  e.Handled = true;
}

Второй способ можно использовать совместно с другими командами без необходимости повторять его повсеместно.

После того, как вы определили команды, подобные этой, вы можете добавить их в любой элемент пользовательского интерфейса. Далее, после того, как окно загружено, я добавляю привязки команд как в Window, так и в MenuItem, а затем добавляю привязку ввода к окну, используя цикл для этого для всех привязок команд. Передаваемый параметр - это само окно, поэтому приведенный выше код знает, какое окно попытаться закрыть.

public partial class SimpleWindow : Window
{
  private void WindowLoaded(object sender, RoutedEventArgs e)
  {
    // ...
    this.CommandBindings.Add(
      new CommandBinding(
        CommandBank.CloseWindow,
        CommandBank.CloseWindowExecute,
        CommandBank.CanExecuteIfParameterIsNotNull));

    foreach (CommandBinding binding in this.CommandBindings)
    {
       RoutedCommand command = (RoutedCommand)binding.Command;
       if (command.InputGestures.Count > 0)
       {
         foreach (InputGesture gesture in command.InputGestures)
         {
           var iBind = new InputBinding(command, gesture);
           iBind.CommandParameter = this;
           this.InputBindings.Add(iBind);
         }
       }
    }

    // menuItemExit is defined in XAML
    menuItemExit.Command = CommandBank.CloseWindow;
    menuItemExit.CommandParameter = this;
    // ...
  }

  // ....
}

У меня также позже есть обработчики событий для событий WindowClosing и WindowClosed, я рекомендую вам сделать фактическую реализацию команд настолько малой и универсальной, насколько это возможно. Как и в этом случае, я не пытался поместить код, который пытается остановить закрытие окна, если есть несохраненные данные, я твердо держал этот код внутри события WindowClosing.

Дайте мне знать, если у вас есть дополнительные вопросы. :)

7 голосов
/ 13 августа 2008

Я написал в блоге о ресурсах по командам WPF вместе с примером в прошлом году на http://blogs.vertigo.com/personal/alanl/Blog/archive/2007/05/31/commands-in-wpf.aspx

Вставка здесь:

Образец главы Адама Натана «Важные новые концепции в WPF: команды»

Статья MSDN: Шаблон команд в WPF

Кейван Найери: Как добавить команды в пользовательский элемент управления WPF

Ян Гриффитс: ввод, команды и обработчики Авалона

Википедия: Шаблон команды

Библиотека MSDN: Обзор команд

Библиотека MSDN: класс привязки команд

Библиотека MSDN: вводные сведения и инструкции по командам

Библиотека MSDN: класс EditingCommands

Библиотека MSDN: класс MediaCommands

Библиотека MSDN: класс ApplicationCommands

Библиотека MSDN: класс NavigationCommands

Библиотека MSDN: класс ComponentCommands

Также скрыт в примерах WPF SDK, есть хороший пример редактирования RichTextBox, который я расширил. Вы можете найти его здесь: RichTextEditor.zip

4 голосов
/ 08 сентября 2008

В сентябрьском выпуске журнала MSDN Брайан Нойес написал отличную статью о RoutedCommand / RoutedEvents !!!

Вот ссылка: http://msdn.microsoft.com/en-us/magazine/cc785480.aspx

3 голосов
/ 12 августа 2008

Особенность XAML в том, что он подходит для «простых» программ, но, к сожалению, он не работает, когда вы хотите выполнять такие вещи, как функции общего доступа. Скажем, у вас есть несколько классов и все интерфейсы пользователя, в которых есть команды, которые никогда не отключались, вам нужно написать метод CanAlwaysExecute для каждого Window или UserControl! Это просто не очень DRY .

Прочитав несколько блогов и попробовав несколько вещей, я решил сделать XAML исключительно для внешнего вида, стилей, анимации и триггеров. Все мои подключения обработчиков событий и команд теперь в коде позади. :)

Кстати, есть еще одна проблема - привязка ввода, чтобы их можно было перехватить, необходимо сосредоточиться на объекте, который содержит привязки ввода. Например, для кратчайшего пути, который вы можете использовать в любое время (скажем, F1, чтобы открыть справку), эта входная привязка должна быть установлена ​​для объекта Window, поскольку она всегда имеет фокус, когда ваше приложение активно. Использование метода кода должно облегчить это, даже когда вы начинаете использовать UserControls, которые могут захотеть добавить привязки ввода к своему родительскому окну.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...