Как найти цель связывания ICommand (элемент управления) - PullRequest
0 голосов
/ 14 октября 2011

Мы используем шаблон MVVM. В представлении я привязал команду сохранения к кнопке:

В модели представления я хотел бы выяснить цель привязки команды сохранения, возможно ли это?

    private Button GetBindingControl(ICommand command)
    {
        // What should I do here:

        return button;
    }

Ответы [ 2 ]

1 голос
/ 14 октября 2011

Как сказал @Diego, это противоречит цели MVVM, потому что мы должны стараться не включать визуальные элементы или элементы управления в модели представлений в MVVM ...

Сказав, что есть два варианта ...

  1. Использование RoutedCommands
  2. Использование прикрепленного поведения.

RoutedCommands нелегко разрешены в MVVM, так как они должны быть тесно связаны с командами элемента UI, то есть в нашем случае Button. Следовательно они также побеждают цель MVVM.

Но MVVM счастливо сосуществует с Привязанными поведениями.

Многие разработчики уклоняются от этой чрезвычайно мощной функции. И мы можем использовать его вместе с RoutedCommands.

В вашем случае

  1. Присоединить к кнопке с делегатом действия.
  2. Присоединить строковый объект в качестве параметра команды.
  3. Внутри поведения установите Button.Command с помощью некоторой команды Routed.
  4. В обработчике выполненного события получите делегат действия кнопки от отправителя / originalsource / source в качестве кнопки, а затем соответственно вызовите свое действие <>, используя e.Parameter строковое значение.

Пример кода ниже ...

Предположим, у вас есть общие кнопки подписи Action<Button, string>

public static class ButtonActionUtilities
{
    public static Action<Button, string> ButtonActionDelegate
    {
        get
        {
            return ExecuteButtonClick;
        }
    }

    public static void ExecuteButtonClick(Button btn, string param)
    {
        MessageBox.Show(
          "You clicked button " + btn.Content + " with parameter " + param);
    }
}

Тогда привязанное поведение будет таким, как показано ниже ...

public static class ButtonAttachedBehavior
{
    public static readonly DependencyProperty ActionDelegateProperty
        = DependencyProperty.RegisterAttached(
            "ActionDelegate",
            typeof(Action<Button, string>),
            typeof(ButtonAttachedBehavior),
            new PropertyMetadata(null, OnActionDelegatePropertyChanged));

    public static Action<Button, string> GetActionDelegate(
                                            DependencyObject depObj)
    {
        return (Action<Button, string>)depObj.GetValue(
                                            ActionDelegateProperty);
    }

    public static void SetActionDelegate(
         DependencyObject depObj, Action<Button, string> value)
    {
        depObj.SetValue(ActionDelegateProperty, value);
    }

    private static void OnActionDelegatePropertyChanged(
        DependencyObject depObj,
        DependencyPropertyChangedEventArgs e)
    {
        if (depObj is Button
            && e.NewValue is Action<Button, string>)
        {               
            ((Button)depObj).Command
                = new RoutedCommand(
                        "ActionRoutedCommand",
                         typeof(ButtonAttachedBehavior));
            ((Button) depObj).CommandBindings.Add(
                new CommandBinding(
                    ((Button) depObj).Command,
                    OnActionRoutedCommandExecuted));
        }
    }

    private static void OnActionRoutedCommandExecuted(
       object sender, ExecutedRoutedEventArgs e)
    {
        var actionDelegate = GetActionDelegate((Button)e.Source);
        actionDelegate((Button) e.Source, (string)e.Parameter);
    }
}

А на XAML это будет выглядеть так ...

      <StackPanel>
         <Button x:Name="TestButton" Content="Test Me" 
            local:ButtonAttachedBehavior.ActionDelegate
                ="{x:Static local:ButtonActionUtilities.ButtonActionDelegate}"
            CommandParameter
                ="{Binding Text, ElementName=ParameterTextBox}"/>

          <TextBox x:Name="ParameterTextBox"/>
      </StackPanel>

Таким образом, с помощью приведенного выше кода вам нужно просто установить ActionDelegate присоединенное свойство для подходящего делегата, и оно выполнит это.

Я бы по-прежнему предлагал вам пересмотреть существующую настройку кода, чтобы отделить поведение кнопок, чтобы сделать его более дружественным к MVVM.

1 голос
/ 14 октября 2011

Это невозможно, и это противоречит цели MVVM (наличие логики пользовательского интерфейса в виртуальной машине независимо от используемых элементов управления)

Возможно, вы могли бы спросить, какую проблему вы пытаетесь решить.

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