我正在做一些简单的应用程序重构以跟随MVVM,我的问题是如何将SelectionChanged事件从我的代码中移出到viewModel?我已经看了一些绑定元素到命令的例子,但是并没有完全掌握它.谁能帮忙解决这个问题.谢谢!
有人可以使用下面的代码提供解决方案吗?非常感谢!
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;
}
}
Run Code Online (Sandbox Code Playgroud)
Pav*_*kov 109
您应该EventTrigger与InvokeCommandActionWindows.Interactivity命名空间结合使用.这是一个例子:
<ListBox ...>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectedItemChangedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
你可以System.Windows.Interactivity去参考Add reference > Assemblies > Extensions.
完整的i命名空间是:xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity".
Cam*_*and 10
这个问题有类似的问题.
WPF MVVM:命令很简单.如何使用RoutedEvent连接View和ViewModel
我处理这个问题的方法是在ViewModel中有一个SelectedItem属性,然后将ListBox的SelectedItem绑定到该属性.
Sni*_*son 10
我知道现在有点晚了,但是 Microsoft 已将其 Xaml.Behaviors 开源,现在只需一个命名空间即可轻松使用交互性。
然后像这样使用它,
<Button Width="150" Style="{DynamicResource MaterialDesignRaisedDarkButton}">
<behaviours:Interaction.Triggers>
<behaviours:EventTrigger EventName="Click">
<behaviours:InvokeCommandAction Command="{Binding OpenCommand}" PassEventArgsToCommand="True"/>
</behaviours:EventTrigger>
</behaviours:Interaction.Triggers>
Open
</Button>
Run Code Online (Sandbox Code Playgroud)
PassEventArgsToCommand="True" 应设置为 True,并且您实现的 RelayCommand 可以采用 RoutedEventArgs 或对象作为模板。如果您使用对象作为参数类型,只需将其转换为适当的事件类型。
该命令看起来像这样,
OpenCommand = new RelayCommand<object>(OnOpenClicked, (o) => { return true; });
Run Code Online (Sandbox Code Playgroud)
命令方法看起来像这样,
private void OnOpenClicked(object parameter)
{
Logger.Info(parameter?.GetType().Name);
}
Run Code Online (Sandbox Code Playgroud)
“参数”将是路由事件对象。
如果你好奇的话,还有日志,
2020-12-15 11:40:36.3600|信息|MyApplication.ViewModels.MainWindowViewModel|RoatedEventArgs
如您所见,记录的 TypeName 是 RoutedEventArgs
RelayCommand 的实现可以在这里找到。
PS:您可以绑定到任何控件的任何事件。就像Window的Closing事件一样,你会得到相应的事件。
你最好的选择是使用Windows.Interactivity.使用EventTriggers一个连接ICommand到任何RoutedEvent.
这篇文章是为了帮助您入门:Silverlight和WPF行为和触发器
要重构这个,你需要改变你的想法.您将不再处理"选择已更改"事件,而是将所选项目存储在viewmodel中.然后,您将使用双向数据绑定,以便在用户选择项目时更新您的viewmodel,并在更改所选项目时更新您的视图.
考虑Microsoft.Xaml.Behaviors.Wpf,Microsoft您可以在该页面中看到它的所有者。
System.Windows.Interactivity.WPF所有者是mthamil,谁能告诉我它可靠吗?
示例Microsoft.Xaml.Behaviors.Wpf:
<UserControl ...
xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
...>
<Button x:Name="button">
<behaviors:Interaction.Triggers>
<behaviors:EventTrigger EventName="Click" SourceObject="{Binding ElementName=button}">
<behaviors:InvokeCommandAction Command="{Binding ClickCommand}" />
</behaviors:EventTrigger>
</behaviors:Interaction.Triggers>
</Button>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
78940 次 |
| 最近记录: |