WPF – MVVM – ComboBox SelectedItem

我在后台和类CategoryViewModel (实现了INotifyPropertyChanged ),它只有一个string类型的属性。 我的ComboBox SelectedItem绑定到Category的实例。 当我更改实例的值时,SelectedItem没有被更新,并且Combobox没有被更改。

编辑:代码

combobox:

  

属性:

 private Category _NodeCategory; public Category NodeCategory { get { return _NodeCategory; } set { _NodeCategory = value; OnPropertyChanged("NodeCategory"); } } [Serializable] public class Category : INotifyPropertyChanged { private string _Name; [XmlAttribute("Name")] public string Name { get { return _Name; } set { _Name = value; OnPropertyChanged("Name"); } } public void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } [field:NonSerialized] public event PropertyChangedEventHandler PropertyChanged; } 

而我正在尝试的是:当我设置

 NodeCategory = some_list_of_other_objects.Category; 

使用适当的DisplayMemberPathCombobox选择该项目

您在此行中设置的类别 –

 NodeCategory = some_list_of_other_objects.Category; 

您的Categories集合中存在的一个( ItemsSource="{Binding Categories}" )应该指向同一个对象。 如果它们不是那么SelectedItem将无法工作。

解决方案1 ​​ –

你也可以尝试像这样使用SelectedValuePath

  

在代码中你可以做这样的事情 –

 private string _NodeCategory; public string NodeCategory { get { return _NodeCategory; } set { _NodeCategory = value; OnPropertyChanged("NodeCategory"); } } 

并设置这样的选定项目 –

 NodeCategory = some_list_of_other_objects.Category.Name; 

并使用这样的选定值 –

 Category selectedCategory = some_list_of_other_objects.FirstOrDefault(cat=> cat.Name == NodeCategory); 

要么

 Category selectedCategory = Categories.FirstOrDefault(cat=> cat.Name == NodeCategory); 

解决方案2 –

另一个可能的解决方案是 –

 NodeCategory = Categories.FirstOrDefault(cat=> cat.Name == some_list_of_other_objects.Category.Name); 

这样,您的NodeCategory属性将具有Categories集合中对象的引用,并且SelectedItem将起作用。

您的XAML需要进行一些修改,但我认为真正的问题在于您发布的代码,我认为这些代码并不能完整地讲述。 对于初学者,您的comboboxItemSource绑定到名为Categories的属性,但您不显示此属性的编码方式或NodeCategory属性最初如何与项同步。

尝试使用以下代码,当用户更改combobox中的值时,您将看到所选项目保持同步。

XAML

      

代码隐藏

 public partial class MainWindow : Window, INotifyPropertyChanged { private ObservableCollection _categories = new ObservableCollection { new Category { Name = "Squares"}, new Category { Name = "Triangles"}, new Category { Name = "Circles"}, }; public MainWindow() { InitializeComponent(); NodeCategory = _categories.First(); this.DataContext = this; } public IEnumerable Categories { get { return _categories; } } private Category _NodeCategory; public Category NodeCategory { get { return _NodeCategory; } set { _NodeCategory = value; OnPropertyChanged("NodeCategory"); } } public void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } public event PropertyChangedEventHandler PropertyChanged; } [Serializable] public class Category : INotifyPropertyChanged { private string _Name; [XmlAttribute("Name")] public string Name { get { return _Name; } set { _Name = value; OnPropertyChanged("Name"); } } public void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } [field: NonSerialized] public event PropertyChangedEventHandler PropertyChanged; } 

从我的小例子:

注意:这只是设置一个字符串(或另一个列表中的类别),但基础知识应该相同:

基本上这样做:

 private void button1_Click(object sender, RoutedEventArgs e) { (this.DataContext as ComboBoxSampleViewModel).SelectCategory("Categorie 4"); } 

这是我的XAML:

     

并在Window的ViewModel中

 class ComboBoxSampleViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } public CategoryList List { get; set; } public ComboBoxSampleViewModel() { this.List = new CategoryList(); NodeCategory = List.Selected; } private ComboBoxSampleItemViewModel nodeCategory; public ComboBoxSampleItemViewModel NodeCategory { get { return nodeCategory; } set { nodeCategory = value; NotifyPropertyChanged("NodeCategory"); } } internal void SelectCategory(string p) { this.List.SelectByName(p); this.NodeCategory = this.List.Selected; } } 

在这个小class的帮助下:

 public class CategoryList { public ObservableCollection Categories { get; set; } public ComboBoxSampleItemViewModel Selected { get; set; } public CategoryList() { Categories = new ObservableCollection(); var cat1 = new ComboBoxSampleItemViewModel() { Name = "Categorie 1" }; var cat2 = new ComboBoxSampleItemViewModel() { Name = "Categorie 2" }; var cat3 = new ComboBoxSampleItemViewModel() { Name = "Categorie 3" }; var cat4 = new ComboBoxSampleItemViewModel() { Name = "Categorie 4" }; Categories.Add(cat1); Categories.Add(cat2); Categories.Add(cat3); Categories.Add(cat4); this.Selected = cat3; } internal void SelectByName(string p) { this.Selected = this.Categories.Where(s => s.Name.Equals(p)).FirstOrDefault(); } } 

而这个Item ViewModel

 public class ComboBoxSampleItemViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } private string name; public string Name { get { return name; } set { name = value; NotifyPropertyChanged("Name"); } } }