MVVMパターンを使用してWPFのSelectionChanged
のComboBox
イベントを発生/処理する方法は?
詳しく説明してください。WPFの初心者です。
私が望むのは、ComboBox
アイテムの選択が変更されたときにいくつかの操作を行うことです。 MVVMの方法でどのように達成できますか?
MVVMソリューション:
ItemsSource
のSelectedItem
およびComboBox
プロパティをViewModelのプロパティにバインドします。
<ComboBox ItemsSource="{Binding MyItems}" SelectedItem="{Binding MySelectedItem}"/>
MainViewModel.cs内:
public ObservableCollection<string> MyItems { get; set; }
private string _mySelectedItem;
public string MySelectedItem
{
get { return _mySelectedItem; }
set
{
// Some logic here
_mySelectedItem = value;
}
}
コードビハインドソリューション:
MVVMを使用したくない場合は、これを使用して追加できます。
<ComboBox SelectionChanged="ComboBox_SelectionChanged" />
そして、これをMainWindow.xaml.csに追加します。
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Some logic here
}
私はこの方法の大ファンです。
xmlns:i="http://schemas.Microsoft.com/expression/2010/interactivity"
<ComboBox Grid.Column="2" DisplayMemberPath="Data.name" ItemsSource="{Binding Model.Regions}" SelectedItem="{Binding Model.SelectedRegion}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding RegionChangedCmd}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
ViewModelはINotifyPropertyChangedを実装する必要があります。
public class MyViewModel : INotifyPropertyChanged
{
private string _mySelectedItem;
public string MySelectedItem
{
get
{
return _mySelectedItem;
}
set
{
if (_mySelectedItem != value)
{
_mySelectedItem = value;
// Perform any pre-notification process here.
if (null != PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs("MySelectedItem"));
}
}
}
}
}
以前に投稿されたXAMLは正しいです:
<ComboBox ItemsSource="{Binding MyItems}" SelectedItem="{Binding MySelectedItem}"/>
これを拡張しただけです ソリューション 上記にあります、Prism Libraryを使用している場合
(そうでない場合、今すぐ読むのをやめて、あなたには何もありません)
私はこのソリューションが本当に好きで、他のどのソリューションよりも優れていると思います。PrismLibraryが提供するそのソリューションを少し強化したいだけです。
そのソリューションは使用しています
<i:InvokeCommandAction Command="{Binding RegionChangedCmd}" />
InvokeCommandAction
の前のi:
に注意してください。これは、InvokeCommandAction
クラスがxmlns:i="http://schemas.Microsoft.com/expression/2010/interactivity"
名前空間に存在することを意味します。これは問題ありませんが、PrismライブラリにはInvokeCommandAction
という同じ名前のまったく同じクラスがあることに注意してください。 xmlns:prism="http://prismlibrary.com/"
名前空間の別の名前空間に存在するだけです。
実際には、次のXAMLを置き換えることができます
<i:InvokeCommandAction Command="{Binding RegionChangedCmd}" />
このXAMLで
<prism:InvokeCommandAction Command="{Binding RegionChangedCmd}" />
OK、これを行うことができます、利点は何ですか?
利点を確認するには、ViewModelで次のコマンドを記述します
public ICommand RegionChangedCmd { get; }
public ViewModelConstructor()
{
RegionChangedCmd = new DelegateCommand<SelectionChangedEventArgs>(RegionChangedCmdExecuted);
}
public void RegionChangedCmdExecuted(SelectionChangedEventArgs e)
{
// e parameter is null if you use <i:InvokeCommandAction>
// e parameter is NOT null if you use <prism:InvokeCommandAction>
}
<i:InvokeCommandAction>
を使用する場合、eパラメーターはnull
eパラメータはNOT null<prism:InvokeCommandAction>
を使用する場合
最初に、物事を明確にしましょう-イベントを変更することはできず、購読することができます。
選択の変更を処理する場所に関する情報を提供していないため、最も一般的なシナリオ-基礎となるViewModelでの処理を想定します。 MVVMによると、ViewModelはViewについて何も知らないため、ViewModelからViewのコントロールのイベントに直接サブスクライブすることはできません。ただし、ViewModelのプロパティをSelectedItem
またはSelectedIndex
のいずれかにバインドできるため、選択が変更されるとトリガーされます。
<ComboBox
SelectedIndex="{Binding SelectedIndexPropertyName}"
... />
view.DataContext
を介してViewModelにアクセスすることにより、Viewの背後にあるコードを処理する他のソリューションがありますが、このような慣行を避けることをお勧めします。