Как выполнить команду в WPF

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

     <ListBox x:Name="myListBox"  Grid.Row="0"
         ItemsSource="{Binding Path=_mySOurce}" 
         ScrollViewer.VerticalScrollBarVisibility="Auto" 
         SelectionChanged="myListBox_SelectionChanged">
    </ListBox>
    <Button Grid.Row="1" x:Name="btnSelect" 
     Command="{Binding Path=SaveCommand}" Content="Select" Margin="396,0,10,0"></Button>

и в моем коде у меня есть

 public ICommand SaveCommand { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        this.SaveCommand = new DelegateCommand<object>(this.OnSaveClick, this.CanSaveExecute);       
    }

    private void myListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {

    }

    private void OnSaveClick(object arg)
    {

        MessageBox.Show("Performed Click");
    }
    private bool CanSaveExecute(object arg)
    {
        if (myListBox.SelectedIndex > 0)
            return true;

        else return false;
    }

Я не могу запустить его при выборе измененного события.

Что мне не хватает?


person Rohit    schedule 24.02.2015    source источник
comment
в myListBox_SelectionChanged запустите его SaveCommand.Execute (параметр)?   -  person puko    schedule 24.02.2015
comment
Если вы хотите запустить эту команду в SelectionChanged, то где находится обработчик этого события?   -  person SaneDeveloper    schedule 24.02.2015
comment
Вот ответ   -  person Mike Eason    schedule 24.02.2015


Ответы (1)


Если вы обрабатываете событие пользовательского интерфейса в своей модели представления, то вы не вообще используете MVVM! Обработка событий пользовательского интерфейса в модели представления полностью нарушает разделение задач, которое обеспечивает MVVM.

Однако краткий ответ таков:

private void myListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (SaveCommand.CanExecute(null)) SaveCommand.Execute(null);
}

Гораздо лучшим решением является добавление еще одного свойства к привязке данных к свойству ListBox.SelectedItem:

<ListBox x:Name="myListBox"  Grid.Row="0" SelectedItem="{Binding CurrentItem}"
    ItemsSource="{Binding Path=_mySOurce}" 
    ScrollViewer.VerticalScrollBarVisibility="Auto" 
    SelectionChanged="myListBox_SelectionChanged" />

Затем установщик для этого свойства CurrentItem будет вызываться всякий раз, когда будет вызываться событие SelectionChanged:

public YourDataType CurrentItem
{
    get { return currentItem; }
    set
    {
        currentItem = value;
        NotifyPropertyChanged("CurrentItem");
        if (SaveCommand.CanExecute(null)) SaveCommand.Execute(null);
    }
}
person Sheridan    schedule 24.02.2015
comment
Я еще не уверен, что хуже: иметь побочные эффекты в установщике свойств (как в этом последнем примере) или НЕ делать этого, потому что это очень, очень удобный и довольно элегантный способ реализовать такое поведение в WPF/ MVVM, своего рода реактивная вещь (если вы не забываете о скрытом побочном эффекте). Интересное обсуждение здесь:programmers.stackexchange.com/ вопросы/82377/ - person heltonbiker; 24.02.2015
comment
Возможно, вы неправильно прочитали свой связанный пост... в сеттерах абсолютно нет упоминаний о «побочных эффектах». Можете ли вы придумать какие-либо недостатки этого кода, потому что я хотел бы услышать об этом, если вы это сделаете? - person Sheridan; 24.02.2015
comment
Довольно спорная проблема: когда кто-то устанавливает свойство, вы обычно не ожидаете других, косвенных вещей, происходящих за вашей спиной. Это поведение прекрасно, когда оно так задумано, и вы помните об этом. Но если с ним должен работать какой-то коллега, поведение неочевидно, с этим нужно разобраться. У меня уже бывало, когда на занятиях по уборке дома забывала зайти в сеттер и переодеться там тоже, а потом вдруг вещи перестают работать. Но я бы не стал слишком беспокоиться об этом, потому что, как я уже сказал, я думаю, что эти шаблоны решают гораздо больше проблем, чем они создают. - person heltonbiker; 24.02.2015