MVVM, Команда привязки данных - PullRequest
0 голосов
/ 19 марта 2011

Я начал использовать привязку данных с шаблоном MVVM в Silverlight.Есть одна проблема для меня.У меня есть список, когда я выбираю элемент, одно свойство в View-Model должно изменить его значение.Я реализовал DelegateCommand и создал собственный класс CommandListBox следующим образом:

public class DelegateCommand<T> : ICommand
{
    private readonly Action<T> _execute;
    private readonly Predicate<T> _canExecute;

    public DelegateCommand(Action<T> execute)
        : this(execute, x => true)
    {
    }

    public DelegateCommand(Action<T> execute, Predicate<T> canExecute)
    {
        if (canExecute == null) throw new ArgumentNullException("canExecute");
        if (execute == null) throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute((T)parameter);
    }

    public event EventHandler CanExecuteChanged;

    public void RaiseCanExecuteChanged()
    {
        CanExecuteChanged.DynamicInvoke(this);//.Raise(this);
    }
}

public class DelegateCommand : DelegateCommand<object>
{
    public DelegateCommand(Action execute)
        : base(execute != null ? x => execute() : (Action<object>)null)
    {
    }

    public DelegateCommand(Action execute, Func<bool> canExecute)
        : base(execute != null ? x => execute() : (Action<object>)null,
                canExecute != null ? x => canExecute() : (Predicate<object>)null)
    {
    }
}

public class CommandListBox : ListBox
{
    public CommandListBox()
    {
        SelectionChanged += (sender, e) =>
        {
            if (Command != null && Command.CanExecute(CommandParameter))
                Command.Execute(CommandParameter);
        };
    }

    public static DependencyProperty CommandProperty =
        DependencyProperty.Register("Command",
                                    typeof(ICommand), typeof(CommandListBox),
                                    new PropertyMetadata(null, CommandChanged));

    private static void CommandChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
    {
        var treeList = source as CommandListBox;
        if (treeList == null) return;

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

    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 (Command != null)
            IsEnabled = Command.CanExecute(CommandParameter);
    }

    public ICommand Command
    {
        get { return GetValue(CommandProperty) as ICommand; }
        set { SetValue(CommandProperty, value); }
    }

    public static DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter",
                                    typeof(object), typeof(CommandListBox),
                                    new PropertyMetadata(null));

    public object CommandParameter
    {
        get { return GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }

}

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

Ответы [ 2 ]

0 голосов
/ 19 марта 2011

Ваш CommandListBox является производным от ListBox, он предоставляет событие SelectionChanged, к которому вы уже присоединяетесь.

SelectionChanged += (sender, e) =>
        {
            if (Command != null && Command.CanExecute(CommandParameter))
                Command.Execute(CommandParameter);
        };

Чтобы получить выбранный предмет, вы можете сделать что-то вроде этого:

  SelectionChanged += (sender, e) =>
            {
                CommandListBox source = sender as CommandListBox; // This is the sender
                if(source != null) // just to be sure
                {
                    var value = source.SelectedItem;
                }    
                if (Command != null && Command.CanExecute(CommandParameter))
                    Command.Execute(CommandParameter);
            };

Помогает ли это?

0 голосов
/ 19 марта 2011

Вы можете привязать свойство SelectedItem вашего списка к соответствующему свойству в вашей ViewModel.

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