WPF - MVVM:以后的SelectionChanged组合框值 [英] WPF - MVVM: ComboBox value after SelectionChanged
问题描述
我是新的C#和MVVM,我已经花了一整天试图让的SelectionChanged一个
。我设法用弄明白要么组合框
我的视图模型的价值 CallMethodAction
或 InvokeCommandAction
与资源:
-
System.Windows.Interactivity.dll
-
Microsoft.Ex pression.Interactions.dll
我的问题是,这两种方法返回之前,它已经改变了组合框的值。任何人都可以解释如何获取值的之后的变化?
我花了几个小时寻遍SO和谷歌的解决方案,所以我不知道如果其他人也有同感。任何意见将是AP preciated!
我的code是如下:
MainWindow.xaml
<窗口x:类=SelectionChange.MainWindow
的xmlns =http://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml
的xmlns:I =CLR的命名空间:System.Windows.Interactivity;装配= System.Windows.Interactivity
xmlns:si=\"clr-namespace:Microsoft.Ex$p$pssion.Interactivity.Core;assembly=Microsoft.Ex$p$pssion.Interactions\"
的xmlns:VM =CLR的命名空间:SelectionChange
标题=主窗口WIDTH =300HEIGHT =300>
< Window.DataContext>
< VM:视图模型/>
< /Window.DataContext>
<网格和GT;
<组合框名称=选择框VerticalAlignment =顶部的SelectedIndex =0>
< I:Interaction.Triggers>
< I:的EventTrigger事件名称=的SelectionChanged>
< SI:CallMethodAction方法名=的SelectionChangedTargetObject ={结合}/>
!< - < I:InvokeCommandAction命令={结合SelectionChangedCommand}CommandParameter ={绑定的ElementName =选择框,路径=文本}/> - >
< /我:&的EventTrigger GT;
< /我:Interaction.Triggers>
< ComboBoxItem CONTENT =项目1/>
< ComboBoxItem CONTENT =项目2/>
< ComboBoxItem CONTENT =项目3/>
< /组合框>
< /网格和GT;
< /窗GT;
ViewModel.cs
命名空间SelectionChange
{
使用系统;
使用System.Windows;
使用System.Windows.Controls的;
使用System.Windows.Input; 公共类视图模型
{
公共视图模型()
{
SelectionChangedCommand =新SelectionChangedCommand();
} 公众的ICommand SelectionChangedCommand
{
得到;
组;
} 公共无效的SelectionChanged(对象发件人,EventArgs的发送)
{
组合框选择框=(组合框)发送;
的MessageBox.show(叫的SelectionChanged:+ SelectBox.Text);
}
}
}
SelectionChangedCommand.cs
命名空间SelectionChange
{
使用系统;
使用System.Windows;
使用System.Windows.Controls的;
使用System.Windows.Input; 公共类SelectionChangedCommand:ICommand的
{
公共SelectionChangedCommand()
{
} 公共事件的EventHandler CanExecuteChanged; 公共BOOL CanExecute(对象参数)
{
返回true;
} 公共无效执行(对象参数)
{
的MessageBox.show(执行的SelectionChangedCommand:+参数);
}
}
}
结果搜索结果
修改:我的解决方案
原来我不明白绑定
不够好,而是试图实现东西在一个相当复杂的方式简单!而不是使用依赖,现在我已经实现了我所需要使用普通绑定。举个例子,我约束的文本框
到的SelectedIndex
的组合框的code>,这将会采用更新的
INotifyPropertyChanged的
。
MainWindow.xaml
<窗口x:类=SelectionChange.MainWindow
的xmlns =http://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml
的xmlns:VM =CLR的命名空间:SelectionChange
标题=主窗口WIDTH =300HEIGHT =300>
< Window.DataContext>
< VM:视图模型/>
< /Window.DataContext>
<网格和GT;
< Grid.ColumnDefinitions>
< ColumnDefinition WIDTH =自动/>
&所述; ColumnDefinition宽度=*/>
< /Grid.ColumnDefinitions> <组合框的SelectedItem ={结合的SelectedItem}的SelectedIndex =0Grid.Column =0VerticalAlignment =评出的>
< ComboBoxItem CONTENT =项目1/>
< ComboBoxItem CONTENT =项目2/>
< ComboBoxItem CONTENT =项目3/>
< /组合框> <! - 文本框来显示组合框的selectedIndex - >
<文本框的文本={结合的SelectedIndex}Grid.Column =1VerticalAlignment =顶部/>
< /网格和GT;
< /窗GT;
ViewModel.cs
命名空间SelectionChange
{
使用系统;
使用System.ComponentModel;
使用System.Windows.Controls的; 公共类视图模型:INotifyPropertyChanged的
{
公共视图模型()
{
} //属性来存储/检索组合框的selectedIndex
私人诠释_SelectedIndex;
公众诠释的SelectedIndex {搞定;组; } //属性绑定到组合框的的SelectedItem
私人ComboBoxItem _SelectedItem;
公共ComboBoxItem的SelectedItem
{
{返回_SelectedItem; }
组
{
_SelectedItem =价值; //的SelectedItem的内容
字符串内容=(字符串)value.Content; //的SelectedItem的母公司(即组合框)
组合框选择框=(组合框)value.Parent; //组合框的selectedIndex
INT指数= SelectBox.SelectedIndex; //存放的SelectedIndex在属性
的SelectedIndex =指数; //提高的PropertyChanged与存储的属性的名称
RaisePropertyChanged(的SelectedIndex);
}
} // INotifyPropertyChanged的
公共事件PropertyChangedEventHandler的PropertyChanged;
私人无效RaisePropertyChanged(字符串属性名)
{
如果(的PropertyChanged!= NULL)
的PropertyChanged(这一点,新PropertyChangedEventArgs(属性名));
}
}
}
为什么不这样做的简单的方法
<组合框了maxHeight =25
的ItemsSource ={绑定源}
的SelectedItem ={结合TheSelectedItem,模式=双向}/>
在您的视图模型声明组合框项目和使用财产来源,使其返回到视图
列表<串GT; _source =新的List<串GT; {项目1,项目2,3项};
公开名单<串GT;资源
{
{返回_source; }
}
然后定义它保存所选的项目一个属性。
字符串_theSelectedItem = NULL;
公共字符串TheSelectedItem
{
{返回_theSelectedItem; }
集合{_theSelectedItem =价值; } // NotifyPropertyChanged
}
另外,不要忘记实现INotifyPropertyChanged接口,同时设置_source
I am new to C# and MVVM, and I've spent all day trying to get the value of a ComboBox
to my ViewModel on SelectionChanged
. I have managed to figure it out using either CallMethodAction
or InvokeCommandAction
with the resources:
System.Windows.Interactivity.dll
Microsoft.Expression.Interactions.dll
My problem is that both these methods return the value of the ComboBox
before it has changed. Could anyone explain how to get the value after the change?
I have spent hours searching through SO and Google for a solution, so I wonder if others are too. Any advice will be appreciated!
My code is below:
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);
}
}
}
Edit: My Solution
It turns out I didn't understand Binding
well enough and instead was trying to implement something simple in a rather complicated way! Instead of using dependencies, I have now achieved what I needed using regular bindings. As an example, I've bound a TextBox
to the SelectedIndex
of the ComboBox
, which gets updated using 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));
}
}
}
Why not do it the simpler way
<ComboBox MaxHeight="25"
ItemsSource="{Binding Source}"
SelectedItem="{Binding TheSelectedItem, Mode=TwoWay}" />
In your ViewModel declare the combo box items and use a property "Source" to return it to the view
List<string> _source = new List<string>{"Item 1", "Item 2", "Item 3"};
public List<string> Source
{
get { return _source; }
}
Then define one property which holds the selected item
string _theSelectedItem = null;
public string TheSelectedItem
{
get { return _theSelectedItem; }
set { _theSelectedItem = value; } // NotifyPropertyChanged
}
Also don't forget to implement the INotifyPropertyChanged interface while setting the _source
这篇关于WPF - MVVM:以后的SelectionChanged组合框值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!