如何在MVVM中处理ComboBox的SelectionChanged事件?

36

对于那些纯粹使用MVVM的人,如何处理ComboBox的SelectionChanged事件而不回到代码后台?

我尝试过例如AttachedBehaviors,但是Event="SelectedChanged"不被支持:

<ComboBox>
    <ComboBoxItem Content="Test1">
        <c:CommandBehaviorCollection.Behaviors>
            <c:BehaviorBinding Event="SelectionChanged" 
                               Command="{Binding SelectedChanged}"
                               CommandParameter="MainBorder123"/>
        </c:CommandBehaviorCollection.Behaviors>
    </ComboBoxItem>
    <ComboBoxItem Content="Test2"/>
    <ComboBoxItem Content="Test3"/>
</ComboBox>
4个回答

85

这篇帖子比较老,但是由于我遇到了同样的问题,以下是我如何解决它(使用框架4.0):思路是使用System.Windows.Interactivity。

在XAML中:

<ComboBox ItemsSource="{Binding Items}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ComboBox>

然后您只需要在您的视图模型中实现SelectionChangedCommand即可。


此外,如果您不需要 Command,还有 CallMethodAction 可用,但需要添加对 Microsoft.Expression.Interactions.dll 的引用。 - markmnl
3
在不给ComboBox命名的情况下,你该如何绑定ComboBox的SelectedItem或SelectedValue? - Maslow
1
@Maslow或其他想将所选项目作为参数传递的人:使用绑定,参见这里。在我的情况下,我给ComboBox命名为"MyCombo",然后绑定是一个简单的{Binding ElementName=MyCombo, Path=SelectedItem} - Paul
5
在添加引用System.Windows.Interactivity后,您需要将该命名空间添加到XAML标题中:xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" - Beauty
4
对于 .NET Core,你需要这个 NuGet 包:https://github.com/Microsoft/XamlBehaviorsWpf。将以下内容添加到你的窗口布局 XML 文件的 <Window/> 标签中:xmlns:i="http://schemas.microsoft.com/xaml/behaviors"。更多信息请参见这里:链接 - S0und

26

我不确定你想要的是否可能,但我做的方法是将SelectedItem简单绑定到视图模型上的属性。然后在属性setter中,调用任何自定义代码,例如根据规则设置其他属性。如果我需要将所选项绑定到一个对象(以便更新其他绑定控件),我也会在setter中设置这个并发送通知。


我认为这种方式最有意义,而且目前为止它对我来说运行良好。感谢您发布这个。 - Aphex
9
我认为这是一种非常痛苦的方法。对于简单的应用程序,使用此方法而不是命令很容易。但它很快变得难以控制。属性应该保存数据,而不是执行操作。它会破坏异步操作,并使得调试更加困难,因为默认情况下 Visual Studio 会跳过属性设置器/获取器。 - Richard June

3

使用数据触发器可以触发不同UI元素上的事件,例如"启用/禁用"或"可见/不可见"

如果您希望所选元素在其他UI元素中显示对象数据,则应使用数据绑定,并将UI数据显示元素的数据上下文设置为绑定到组合框中当前选定的项目。


如果我只想更改XAML,那么我可以做到这一点,但是如果我想使用组合框来执行XAML无法完成的操作,例如加载新的资源文件并将其附加到当前窗口,或者更改数据库中的某些数据等,该怎么办? - Edward Tanguay
然后,您可以使用绑定将您的视图模型绑定到组合框SelectionChanged事件。我不确定您在哪里可以找到示例,但Karl Shifflet和Josh Smith是我寻求MVVM帮助的两个主要博客,他们的博客链接如下。http://karlshifflett.wordpress.com/2009/06/03/troubleshooting-silverlight-3-broken-bindings/http://joshsmithonwpf.wordpress.com/2009/05/20/device-specific-interaction-logic-in-an-mvvm-application/很抱歉我无法提供更多具体信息,因为我自己对WPF和MVVM还比较新。 - Peter
糟糕,我忘记提到Karl Shifflet一直在进行大量的WPF业务线活动,请在他的博客上查看,其中包含一些优秀的PowerPoint示例和代码样本。 - Peter

0

对于较新版本的WPF

  1. 安装Microsoft.Xaml.Behaviors.Wpf

  2. 使用命名空间 xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

  3. 然后下拉框应该是

<ComboBox ItemsSource="{Binding Items}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ComboBox>

注意:代码完全没有变化,唯一需要的是Nuget包和更新命名空间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接