Хороший подход к событиям в MVVM - PullRequest
1 голос
/ 08 октября 2009

Так что я столкнулся с этой проблемой, пытаясь реализовать MVVM. AFAIK лучший способ выполнить метод в классе ViewModel - через CommandBinding.

<Button Command={Binding DoSomethingCommand} />

Только на этот раз мне нужно что-то сделать при двойном щелчке ListBoxItem, а ListBoxItem не реализует ICommandSource. Поэтому мне интересно, как лучше всего это сделать, если таковой имеется.

Спасибо!

Edit:

Я просто придумал способ, но он кажется довольно хакерским. Что если я выставлю событие ListBox.DoubleClick, и мой класс ViewModel подписывается на него и запускает правильный метод при срабатывании DoubleClick?

Ответы [ 3 ]

5 голосов
/ 10 октября 2009

Вы можете обработать событие в файле code-behind и вызвать метод объекта ViewModel. На мой взгляд, это намного лучше, чем начинать взламывать. :-) Я не передам перенаправленное событие WPF объекту ViewModel.

Кто сказал, что выделение кода запрещено? Шаблон Model-View-ViewModel определенно нет.

2 голосов
/ 08 октября 2009

Вы можете использовать прикрепленное поведение.

Смотрите здесь: http://geekswithblogs.net/HouseOfBilz/archive/2009/05/29/adventures-in-mvvm-ndash-commanding-with-list-boxes.aspx

0 голосов
/ 08 октября 2009

Silverlight не содержит командную кнопку, такую ​​как кнопка в WPF. Чтобы обойти это, мы создадим пользовательский элемент управления, который будет содержать команду и сопоставит это событие с командой. Нечто подобное должно работать.

public class CommandListBoxItem : ListBoxItem
{
    public CommandListBoxItem()
    {
        DoubleClick += (sender, e) =>
        {
            if (Command != null && Command.CanExecute(CommandParameter))
                Command.Execute(CommandParameter);
        };
    }

    #region Bindable Command Properties

    public static DependencyProperty DoubleClickCommandProperty =
        DependencyProperty.Register("DoubleClickCommand",
                                    typeof(ICommand), typeof(CommandListBoxItem),
                                    new PropertyMetadata(null, DoubleClickCommandChanged));

    private static void DoubleClickCommandChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
    {
        var item = source as CommandListBoxItem;
        if (item == null) return;

        item.RegisterCommand(args.OldValue as ICommand, args.NewValue as ICommand);
    }

    public ICommand DoubleClickCommand
    {
        get { return GetValue(DoubleClickCommandProperty) as ICommand; }
        set { SetValue(DoubleClickCommandProperty, value); }
    }

    public static DependencyProperty DoubleClickCommandParameterProperty =
        DependencyProperty.Register("DoubleClickCommandParameter",
                                    typeof(object), typeof(CommandListBoxItem),
                                    new PropertyMetadata(null));

    public object DoubleClickCommandParameter
    {
        get { return GetValue(DoubleClickCommandParameterProperty); }
        set { SetValue(DoubleClickCommandParameterProperty, value); }
    } 

    #endregion

    private void RegisterCommand(ICommand oldCommand, ICommand newCommand)
    {
        if (oldCommand != null)
            oldCommand.CanExecuteChanged -= HandleCanExecuteChanged;

        if (newCommand != null)
            newCommand.CanExecuteChanged += HandleCanExecuteChanged;

        HandleCanExecuteChanged(newCommand, EventArgs.Empty);
    }

    private void HandleCanExecuteChanged(object sender, EventArgs args)
    {
        if (DoubleClickCommand != null)
            IsEnabled = DoubleClickCommand.CanExecute(DoubleClickCommandParameter);
    }      
}

Затем, когда вы создаете свои ListBoxItems, вы привязываетесь к новому свойству Command.

<local:CommandListBoxItem DoubleClickCommand="{Binding ItemDoubleClickedCommand}" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...