Tôi mới dùng C# và MVVM, và tôi đã dành cả ngày cố gắng lấy giá trị ComboBox
cho ViewModel của tôi trên SelectionChanged
. Tôi đã cố gắng tìm nó bằng cách sử dụng một trong hai CallMethodAction
hoặc InvokeCommandAction
với các nguồn lực:WPF - MVVM: Giá trị ComboBox sau khi chọnChuyển đổi
System.Windows.Interactivity.dll
Microsoft.Expression.Interactions.dll
Vấn đề của tôi là rằng cả hai phương pháp này trả về giá trị của ComboBox
trước khi nó đã thay đổi . Bất kỳ ai có thể giải thích cách nhận giá trị sau thay đổi?
Tôi đã dành hàng giờ tìm kiếm thông qua SO và Google để có giải pháp, vì vậy tôi tự hỏi liệu những người khác cũng vậy. Mọi lời khuyên sẽ được đánh giá cao!
Mã của tôi là dưới đây:
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: Giải pháp của tôi
Hóa ra tôi không hiểu Binding
cũng đủ và thay vào đó đã cố gắng để thực hiện một cái gì đó đơn giản theo một cách khá phức tạp! Thay vì sử dụng các phụ thuộc, tôi đã đạt được những gì tôi cần bằng cách sử dụng các ràng buộc thường xuyên. Ví dụ: tôi đã gắn một số TextBox
vào số SelectedIndex
của số ComboBox
, được cập nhật bằng cách sử dụng 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));
}
}
}
Nếu tôi hiểu những gì bạn đang cố gắng làm, tôi nghĩ điều này sẽ giúp http://stackoverflow.com/questions/4765362/mvvm-combobox -ràng buộc – kenny
Tôi sẽ chỉ thả một ý tưởng cho bạn. Làm thế nào về bạn ràng buộc SelectedItems bất động sản cho một tài sản trong ViewModel của bạn với chế độ ràng buộc TwoWay? Không cần nghe sự kiện SelectionChanged hoặc tạo lệnh. Bất cứ khi nào giá trị SelectedItems được thay đổi, bạn sẽ nhận được thông báo bên trong setter của thuộc tính của bạn trong ViewModel. Hãy dùng thử. –