WPF - MVVM:SelectionChanged 后的 ComboBox 值
Posted
技术标签:
【中文标题】WPF - MVVM:SelectionChanged 后的 ComboBox 值【英文标题】:WPF - MVVM: ComboBox value after SelectionChanged 【发布时间】:2013-11-06 09:16:11 【问题描述】:我是 C# 和 MVVM 的新手,我整天都在尝试将 ComboBox
的值传递给 SelectionChanged
上的 ViewModel。我已经设法使用CallMethodAction
或InvokeCommandAction
和资源来解决这个问题:
System.Windows.Interactivity.dll
Microsoft.Expression.Interactions.dll
我的问题是,这两种方法都返回 ComboBox
的值,然后再更改。任何人都可以解释如何在 更改之后获取值?
我花了几个小时在 SO 和 Google 中搜索解决方案,所以我想知道其他人是否也在这样做。任何建议将不胜感激!
我的代码如下:
MainWindow.xaml
<Window x:Class="SelectionChange.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:si="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
xmlns:vm="clr-namespace:SelectionChange"
Title="MainWindow" Width="300" Height="300">
<Window.DataContext>
<vm:ViewModel />
</Window.DataContext>
<Grid>
<ComboBox Name="SelectBox" VerticalAlignment="Top" SelectedIndex="0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<si:CallMethodAction MethodName="SelectionChanged" TargetObject="Binding" />
<!--<i:InvokeCommandAction Command="Binding SelectionChangedCommand" CommandParameter="Binding ElementName=SelectBox, Path=Text" />-->
</i:EventTrigger>
</i:Interaction.Triggers>
<ComboBoxItem Content="Item 1" />
<ComboBoxItem Content="Item 2" />
<ComboBoxItem Content="Item 3" />
</ComboBox>
</Grid>
</Window>
ViewModel.cs
namespace SelectionChange
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
public class ViewModel
public ViewModel()
SelectionChangedCommand = new SelectionChangedCommand();
public ICommand SelectionChangedCommand
get;
set;
public void SelectionChanged(object sender, EventArgs e)
ComboBox SelectBox = (ComboBox)sender;
MessageBox.Show("Called SelectionChanged: " + SelectBox.Text);
SelectionChangedCommand.cs
namespace SelectionChange
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
public class SelectionChangedCommand : ICommand
public SelectionChangedCommand()
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
return true;
public void Execute(object parameter)
MessageBox.Show("Executed SelectionChangedCommand: " + parameter);
编辑:我的解决方案
原来我对Binding
的理解不够好,而是试图以相当复杂的方式实现一些简单的东西!我现在没有使用依赖项,而是使用常规绑定实现了我所需要的。例如,我将TextBox
绑定到ComboBox
的SelectedIndex
,使用INotifyPropertyChanged
进行更新。
MainWindow.xaml
<Window x:Class="SelectionChange.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:SelectionChange"
Title="MainWindow" Width="300" Height="300">
<Window.DataContext>
<vm:ViewModel />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ComboBox SelectedItem="Binding SelectedItem" SelectedIndex="0" Grid.Column="0" VerticalAlignment="Top">
<ComboBoxItem Content="Item 1" />
<ComboBoxItem Content="Item 2" />
<ComboBoxItem Content="Item 3" />
</ComboBox>
<!-- TextBox to display the ComboBox's SelectedIndex -->
<TextBox Text="Binding SelectedIndex" Grid.Column="1" VerticalAlignment="Top" />
</Grid>
</Window>
ViewModel.cs
namespace SelectionChange
using System;
using System.ComponentModel;
using System.Windows.Controls;
public class ViewModel : INotifyPropertyChanged
public ViewModel()
// Property to store / retrieve ComboBox's SelectedIndex
private int _SelectedIndex;
public int SelectedIndex get; set;
// Property to bind to ComboBox's SelectedItem
private ComboBoxItem _SelectedItem;
public ComboBoxItem SelectedItem
get return _SelectedItem;
set
_SelectedItem = value;
// SelectedItem's Content
string Content = (string)value.Content;
// SelectedItem's parent (i.e. the ComboBox)
ComboBox SelectBox = (ComboBox)value.Parent;
// ComboBox's SelectedIndex
int Index = SelectBox.SelectedIndex;
// Store the SelectedIndex in the property
SelectedIndex = Index;
// Raise PropertyChanged with the name of the stored property
RaisePropertyChanged("SelectedIndex");
// INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string PropertyName)
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
【问题讨论】:
如果我理解你想要做什么,我认为这将有助于***.com/questions/4765362/mvvm-combobox-binding 我只是给你一个想法。如何使用绑定模式 TwoWay 将 SelectedItems 属性绑定到 ViewModel 中的属性?无需监听 SelectionChanged 事件或创建命令。每当 SelectedItems 值发生更改时,您都会在 ViewModel 中属性的设置器内收到通知。试试看。为什么不做更简单的方法
<ComboBox MaxHeight="25"
ItemsSource="Binding Source"
SelectedItem="Binding TheSelectedItem, Mode=TwoWay" />
在您的 ViewModel 中声明组合框项目并使用属性“Source”将其返回给视图
List<string> _source = new List<string>"Item 1", "Item 2", "Item 3";
public List<string> Source
get return _source;
然后定义一个包含所选项目的属性
string _theSelectedItem = null;
public string TheSelectedItem
get return _theSelectedItem;
set _theSelectedItem = value; // NotifyPropertyChanged
另外不要忘记在设置_source时实现INotifyPropertyChanged接口
【讨论】:
这与我最终得到的结果最接近,我想,这取决于你想用 ComboBox 做什么,可能是解决方案(对于其他人)。 @aks81,谢谢你的回答!【参考方案2】:如果您只想在当前项目更改时收到通知,为什么不使用已经是 WPF 一部分的工具而不是所有这些依赖项。
首先获取您的集合的底层视图并在其上使用 CurrentChanged 事件。
ComboBoxList = new ObservableCollection<string>();
var view = CollectionViewSource.GetDefaultView(ComboBoxList);
view.MoveCurrentTo(ComboBoxList[0]);
view.CurrentChanged += new EventHandler(ComboBoxCurrentChanged);
在您的 xaml 中,您只需绑定您的集合并将 IsSynchronizedWithCurrentItem
设置为 true。
<ComboBox IsSynchronizedWithCurrentItem="True" ItemsSource="Binding ComboBoxList"/>
【讨论】:
以上是关于WPF - MVVM:SelectionChanged 后的 ComboBox 值的主要内容,如果未能解决你的问题,请参考以下文章