WPF绑定UI事件到ViewModel中的命令

我正在做一些简单的应用程序的重构,以遵循MVVM和我的问题是如何将一个SelectionChanged事件移出我的代码后面的viewModel? 我已经看了一些绑定元素的命令的例子,但并不完全掌握它。 任何人都可以协助这个。 谢谢!

任何人都可以使用下面的代码提供解决scheme? 非常感谢!

public partial class MyAppView : Window { public MyAppView() { InitializeComponent(); this.DataContext = new MyAppViewModel (); // Insert code required on object creation below this point. } private void contactsList_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) { //TODO: Add event handler implementation here. //for each selected contact get the labels and put in collection ObservableCollection<AggregatedLabelModel> contactListLabels = new ObservableCollection<AggregatedLabelModel>(); foreach (ContactListModel contactList in contactsList.SelectedItems) { foreach (AggregatedLabelModel aggLabel in contactList.AggLabels) { contactListLabels.Add(aggLabel); } } //aggregate the contactListLabels by name ListCollectionView selectedLabelsView = new ListCollectionView(contactListLabels); selectedLabelsView.GroupDescriptions.Add(new PropertyGroupDescription("Name")); tagsList.ItemsSource = selectedLabelsView.Groups; } } 

您应该使用EventTrigger与Windows.Interactivity命名空间中的InvokeCommandAction结合使用。 这里是一个例子:

 <ListBox ...> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged"> <i:InvokeCommandAction Command="{Binding SelectedItemChangedCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </ListBox> 

您可以通过Add reference > Assemblies > Extensions来引用System.Windows.Interactivity

完整的命名空间是: xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

这个问题有一个类似的问题。

WPF MVVM:命令很简单。 如何连接View和ViewModel与RoutedEvent

我处理这个问题的方法是在ViewModel中有一个SelectedItem属性,然后绑定你的ListBox的SelectedItem或其他任何属性。

你最好的select是使用Windows.Interactivity 。 使用EventTriggersICommand附加到任何RoutedEvent

这里是一篇文章,让你开始: Silverlight和WPF的行为和触发器

要重构这个,你需要改变你的想法。 您将不再处理“select已更改”事件,而是将选定的项存储在您的视图模型中。 然后,您将使用双向数据绑定,以便当用户select一个项目时,您的视图模型被更新,当您更改选定的项目时,您的视图更新。

我会在这个问题上回答最好的答案

基本上,您的视图模型将包含所有项目的列表和选定项目的列表。 然后,您可以将行为附加到您的列表框中,以pipe理所选项目的列表。

这样做意味着在代码背后没有任何东西,xaml很容易遵循,行为也可以在应用程序的其他地方重新使用。

 <ListBox ItemsSource="{Binding AllItems}" Demo:SelectedItems.Items="{Binding SelectedItems}" SelectionMode="Multiple" /> 

有时绑定事件的解决scheme通过交互触发命令不起作用,当需要绑定自定义usercontrol事件时。 在这种情况下,您可以使用自定义行为。

声明绑定行为,如:

 public class PageChangedBehavior { #region Attached property public static ICommand PageChangedCommand(DependencyObject obj) { return (ICommand)obj.GetValue(PageChangedCommandProperty); } public static void SetPageChangedCommand(DependencyObject obj, ICommand value) { obj.SetValue(PageChangedCommandProperty, value); } public static readonly DependencyProperty PageChangedCommandProperty = DependencyProperty.RegisterAttached("PageChangedCommand", typeof(ICommand), typeof(PageChangedBehavior), new PropertyMetadata(null, OnPageChanged)); #endregion #region Attached property handler private static void OnPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as PageControl; if (control != null) { if (e.NewValue != null) { control.PageChanged += PageControl_PageChanged; } else { control.PageChanged -= PageControl_PageChanged; } } } static void PageControl_PageChanged(object sender, int page) { ICommand command = PageChangedCommand(sender as DependencyObject); if (command != null) { command.Execute(page); } } #endregion 

}

然后将其绑定到xaml中的命令:

  <controls:PageControl Grid.Row="2" CurrentPage="{Binding Path=UsersSearchModel.Page,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" PerPage="{Binding Path=UsersSearchModel.PageSize,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Count="{Binding Path=UsersSearchModel.SearchResults.TotalItemCount}" behaviors:PageChangedBehavior.PageChangedCommand="{Binding PageChangedCommand}"> </controls:PageControl> 

正如@Cameron MacFarland所提到的,我只是简单地将双向绑定到viewModel上的一个属性。 在属性设置器中,您可以执行任何您需要的逻辑,例如添加到联系人列表,具体取决于您的要求。

但是,我不一定会调用属性“SelectedItem”,因为viewModel不应该知道视图层以及它如何与它的属性进行交互。 我会把它叫做CurrentContact之类的东西。

显然这是除非你只是想创build命令作为练习练习等。

 <ListBox SelectionChanged="{eb:EventBinding Command=SelectedItemChangedCommand, CommandParameter=$e}"> </ListBox> 

命令

{eb:EventBinding}(简单的命名模式来查找命令)

{eb:EventBinding Command = CommandName}

CommandParameter

$ e(EventAgrs)

$ this或$ this.Property

https://github.com/JonghoL/EventBindingMarkup