Решают ли маршрутизируемые команды WPF проблему или ухудшают ее?

StackOverflow https://stackoverflow.com/questions/466699

  •  19-08-2019
  •  | 
  •  

Вопрос

Насколько я понимаю, цель шаблона «Команда» — помочь отделить взаимодействие пользовательского интерфейса от логики приложения.При правильно реализованных командах щелчок по пункту меню «Печать» может привести к такой цепочке взаимодействий:

(button) ---click executes command----> (command) ---calls Print() in app logic ---> (logic)

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

Я изучал команды WPF и по большей части видел, как они реализовали этот шаблон.Тем не менее, я чувствую, что в определенной степени они сложный шаблон «Команда» и сумел реализовать его таким образом, что вам не рекомендуется отделять пользовательский интерфейс от логики приложения.

Например, рассмотрим это простое окно WPF, в котором есть кнопка для вставки текста в текстовое поле:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Paste"
                        Executed="CommandBinding_Executed"/>
    </Window.CommandBindings>
    <StackPanel>
        <TextBox x:Name="txtData" />
        <Button Command="Paste" Content="Paste" />
    </StackPanel>
</Window>

Вот код:

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ApplicationCommands.Paste.Execute(null, txtData);
        }
    }
} 

Что я получил от команды?Мне кажется, что я мог бы так же легко поместить код из обработчика событий привязки команды в файл кнопки. Click событие.Конечно, теперь я могу связать несколько элементов пользовательского интерфейса с командой «Вставить», и мне нужно использовать только один обработчик событий, но что, если я хочу вставить в несколько разных текстовых полей?Мне пришлось бы усложнить логику обработчика событий или написать больше обработчиков событий.Итак, теперь я чувствую, что у меня есть это:

(button) ---executes Routed Command---> (Window) ---executes command binding----(command binding)
(logic) <---calls application logic--- (event handler) <-----raises event --------------|

Что мне здесь не хватает?Мне это кажется дополнительным слоем косвенности.

Это было полезно?

Решение

В дополнение к уже упомянутым вещам в вашем конкретном примере вставки вы забыли свойства CommandTarget и CommandParameter. Для Вставки вы можете указать TextBox, установив в качестве CommandTarget.

Эти свойства абсолютно необходимы, если вы хотите использовать одну и ту же RoutedCommand из разных элементов управления. Они позволяют предоставить обработчику Executed некоторую информацию о контексте, в котором вызывается команда.

Другие советы

Возможно, вы путаете понятия.

Интерфейс ICommand поддерживает шаблон команды. Это позволяет вам абстрагировать действия пользователя в повторно используемый класс.

Маршрутизированные команды - это особая реализация <=>, которая ищет обработчики в визуальном дереве. Они особенно полезны для команд, которые могут быть реализованы многими различными элементами управления, и вы хотите, чтобы текущий элемент управления обрабатывал их. Подумайте, скопируйте / вставьте. Там может быть целый набор элементов управления, которые могут обрабатывать его, но с помощью перенаправленной команды система маршрутизируемых команд автоматически найдет правильный элемент управления для обработки команды на основе фокуса.

Я бы предпочел использовать RoutedCommands и RoutedUICommands при создании элементов управления.Например, TextBox реализует для вас UndoCommand, а входной формат уже привязан к Ctrl+З.Однако при построении моделей представления я предпочитаю использовать собственный ICommand с внутренними реализациями Execute и CanExecute.DelegateCommand обеспечивает это в Prism.Это позволяет разработчику представления/xaml беспокоиться только о команде, а не о правильных обработчиках Execute/CanExecute.Это позволит создать более выразительную модель представления.

пс.Команды делегата пока не работают (элегантно) с InputBindings.Может кто-нибудь из Microsoft это исправить, пожалуйста!

Они могут быть излишними для некоторых вещей, но вы получаете некоторые полезные преимущества, такие как CanExecute, которые могут автоматически включать / отключать кнопки / элементы меню, когда команда недоступна (например, текст не выделен и т. д.). Вы также можете выполнять командные операции в Blend без использования кода, что отлично подходит для дизайнеров.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top