我正在使用MVVM模式,并且ComboBox
绑定到viewmodel中的属性,如下所示:
<ComboBox ItemsSource="{Binding Path=ItemCollection}"
SelectedItem="{Binding Path=SelectedItem}">
</ComboBox>
这很好用。在viewModel我有
private MyData _selectedItem;
public List<MyData> ItemCollection { get; set; }
public MyData SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
RaisePropertyChanged();
}
}
也可以。 ItemCollection绑定到ComboBox的ItemSource,当在ComboBox中选择新项时,SelectedItem会更新。
我想在特定情况下手动更改SelectedItem。像这样(为了简单起见,我跳过空检查):
public MyData SelectedItem
{
get { return _selectedItem; }
set
{
if (value.Name == "Jump to the First item")
_selectedItem = ItemCollection.First();
else
_selectedItem = value;
RaisePropertyChanged();
}
}
这假设MyData类型具有名为Name的字符串属性。
问题是如果条件语句为真,ComboBox的ItemSource将会更新,但是comboBox的实际可见选择不会。
为了给出一些上下文,comboBox实际上绑定到一个CompositeCollection,其中有一个项目被设置为按钮,所以当单击时会打开一个对话框,对话框的结果是确定应该选择comboBox中的哪个项目.. - 无论我做什么,“按钮”将始终保持选中状态。
答案 0 :(得分:1)
您的INotifyPropertyChanged接口是否正确实施?
通常你会把你的财产名称,例如SelectedItem在调用函数时使用。
引发PropertyChanged事件以下MSDN提供的示例。 https://msdn.microsoft.com/en-us/library/ms743695(v=vs.110).aspx
namespace SDKSample
{
// This class implements INotifyPropertyChanged
// to support one-way and two-way bindings
// (such that the UI element updates when the source
// has been changed dynamically)
public class Person : INotifyPropertyChanged
{
private string name;
// Declare the event
public event PropertyChangedEventHandler PropertyChanged;
public Person()
{
}
public Person(string value)
{
this.name = value;
}
public string PersonName
{
get { return name; }
set
{
name = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("PersonName");
}
}
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
}
}
答案 1 :(得分:1)
问题是comboBox在尝试设置所选项目时遇到困惑,而它已经在设置另一个选定项目的过程中。
解决方法是将IsAsync属性设置为true,以便异步设置SelectedItem。
<ComboBox ItemsSource="{Binding Path=ItemCollection}"
SelectedItem="{Binding Path=SelectedItem, IsAsync=True}">
</ComboBox>
执行此操作时,在mainthread上调用代码非常重要:
Application.Current.Dispatcher.Invoke(() =>
{
/* code here */
}
});