C# 如何在wpf中将两个组合框绑定在一起
我有两个组合框,一个包含“项目”列表,另一个包含“子项目”列表 子项列表取决于当前选定的项 我已经完成了大部分工作(通过将子项的ItemSource绑定到PossibleSubitems属性),但是问题是当我更改了项并且子项对于新项不再有效时。在这种情况下,我只想选择第一个有效的子项,但是我得到一个空白的组合框。注意,我认为类中的属性设置正确,但绑定似乎没有正确反映它 这里有一些代码来告诉你我在做什么。在这种情况下,我有: “项目1”,可以包含子项目A或子项目B,以及 “项目2”,可以有子项目B或子项目C 当我选择子项A时切换到项目2时,问题就出现了 XAMLC# 如何在wpf中将两个组合框绑定在一起,c#,wpf,mvvm,binding,combobox,C#,Wpf,Mvvm,Binding,Combobox,我有两个组合框,一个包含“项目”列表,另一个包含“子项目”列表 子项列表取决于当前选定的项 我已经完成了大部分工作(通过将子项的ItemSource绑定到PossibleSubitems属性),但是问题是当我更改了项并且子项对于新项不再有效时。在这种情况下,我只想选择第一个有效的子项,但是我得到一个空白的组合框。注意,我认为类中的属性设置正确,但绑定似乎没有正确反映它 这里有一些代码来告诉你我在做什么。在这种情况下,我有: “项目1”,可以包含子项目A或子项目B,以及 “项目2”,可以有子项目B
代码隐藏:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
namespace WpfApplication1
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
// List of potential Items, used to populate the options for the Items combo box
public ObservableCollection<string> PossibleItems
{
get
{
ObservableCollection<string> retVal = new ObservableCollection<string>();
retVal.Add("Item 1");
retVal.Add("Item 2");
return retVal;
}
}
// List of potential Items, used to populate the options for the Subitems combo box
public ObservableCollection<string> PossibleSubitems
{
get
{
ObservableCollection<string> retVal = new ObservableCollection<string>();
if (CurrentItem == PossibleItems[0])
{
retVal.Add("Subitem A");
retVal.Add("Subitem B");
}
else
{
retVal.Add("Subitem B");
retVal.Add("Subitem C");
}
return retVal;
}
}
// Track the selected Item
private string _currentItem;
public string CurrentItem
{
get { return _currentItem; }
set
{
_currentItem = value;
// Changing the item changes the possible sub items
NotifyPropertyChanged("PossibleSubitems");
}
}
// Track the selected Subitem
private string _currentSubitem;
public string CurrentSubitem
{
get { return _currentSubitem; }
set
{
if (PossibleSubitems.Contains(value))
{
_currentSubitem = value;
}
else
{
_currentSubitem = PossibleSubitems[0];
// We're not using the valuie specified, so notify that we have in fact changed
NotifyPropertyChanged("CurrentSubitem");
}
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
CurrentItem = PossibleItems[0];
CurrentSubitem = PossibleSubitems[0];
}
public event PropertyChangedEventHandler PropertyChanged;
internal void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
使用系统;
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.Windows;
命名空间WpfApplication1
{
公共部分类主窗口:窗口,INotifyPropertyChanged
{
//潜在项目列表,用于填充项目组合框的选项
公众可观察到的收集可能性
{
得到
{
ObservableCollection retVal=新的ObservableCollection();
检索添加(“第1项”);
检索添加(“第2项”);
返回返回;
}
}
//潜在项目列表,用于填充子项目组合框的选项
公共可观测收集可能的子项
{
得到
{
ObservableCollection retVal=新的ObservableCollection();
如果(CurrentItem==PossibleItems[0])
{
检索添加(“子项目A”);
检索添加(“子项B”);
}
其他的
{
检索添加(“子项B”);
检索添加(“子项目C”);
}
返回返回;
}
}
//跟踪所选项目
私有字符串_currentItem;
公共字符串CurrentItem
{
获取{return\u currentItem;}
设置
{
_currentItem=值;
//更改项会更改可能的子项
NotifyPropertyChanged(“可能的子项”);
}
}
//跟踪选定的子项
私有字符串_currentSubitem;
公共字符串子项
{
获取{return\u currentSubitem;}
设置
{
if(可能的ubitems.Contains(value))
{
_当前子项=值;
}
其他的
{
_currentSubitem=可能的子项[0];
//我们没有使用指定的值,因此请通知我们实际上已更改
NotifyPropertyChanged(“当前子项”);
}
}
}
公共主窗口()
{
初始化组件();
this.DataContext=this;
CurrentItem=PossibleItems[0];
CurrentSubitem=可能的子项[0];
}
公共事件属性更改事件处理程序属性更改;
内部无效NotifyPropertyChanged(字符串propertyName=“”)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
}
我重新编写了我自己的示例-将其代码保留在后面,以免与您的示例偏离太多。另外,我使用的是.NET 4.5,因此不必在OnPropertyChanged调用中提供属性名称-如果在.NET 4.0中,则需要插入它们。这适用于所有场景
实际上,我建议按照MVVM模式在视图模型中定位此代码。除了DataContext的绑定之外,它看起来与这个实现没有太大的不同
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
namespace WpfApplication1
{
public partial class MainWindow: Window, INotifyPropertyChanged
{
private string _currentItem;
private string _currentSubitem;
private ObservableCollection<string> _possibleItems;
private ObservableCollection<string> _possibleSubitems;
public MainWindow()
{
InitializeComponent();
LoadPossibleItems();
CurrentItem = PossibleItems[0];
UpdatePossibleSubItems();
DataContext = this;
CurrentItem = PossibleItems[0];
CurrentSubitem = PossibleSubitems[0];
PropertyChanged += (s, o) =>
{
if (o.PropertyName != "CurrentItem") return;
UpdatePossibleSubItems();
ValidateCurrentSubItem();
};
}
private void ValidateCurrentSubItem()
{
if (!PossibleSubitems.Contains(CurrentSubitem))
{
CurrentSubitem = PossibleSubitems[0];
}
}
public ObservableCollection<string> PossibleItems
{
get { return _possibleItems; }
private set
{
if (Equals(value, _possibleItems)) return;
_possibleItems = value;
OnPropertyChanged();
}
}
public ObservableCollection<string> PossibleSubitems
{
get { return _possibleSubitems; }
private set
{
if (Equals(value, _possibleSubitems)) return;
_possibleSubitems = value;
OnPropertyChanged();
}
}
public string CurrentItem
{
get { return _currentItem; }
private set
{
if (value == _currentItem) return;
_currentItem = value;
OnPropertyChanged();
}
}
public string CurrentSubitem
{
get { return _currentSubitem; }
set
{
if (value == _currentSubitem) return;
_currentSubitem = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void LoadPossibleItems()
{
PossibleItems = new ObservableCollection<string>
{
"Item 1",
"Item 2"
};
}
private void UpdatePossibleSubItems()
{
if (CurrentItem == PossibleItems[0])
{
PossibleSubitems = new ObservableCollection<string>
{
"Subitem A",
"Subitem B"
};
}
else if (CurrentItem == PossibleItems[1])
{
PossibleSubitems = new ObservableCollection<string>
{
"Subitem B",
"Subitem C"
};
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.Runtime.CompilerServices;
使用System.Windows;
命名空间WpfApplication1
{
公共部分类主窗口:窗口,INotifyPropertyChanged
{
私有字符串_currentItem;
私有字符串_currentSubitem;
私人可观察收集(可能的);;
私人可观察收集(可能的子项);;
公共主窗口()
{
初始化组件();
LoadPossibleItems();
CurrentItem=PossibleItems[0];
UpdatePossibleSubItems();
DataContext=this;
CurrentItem=PossibleItems[0];
CurrentSubitem=可能的子项[0];
属性更改+=(s,o)=>
{
如果(o.PropertyName!=“CurrentItem”)返回;
UpdatePossibleSubItems();
ValidateCurrentSubItem();
};
}
私有void ValidateCurrentSubItem()
{
如果(!PossibleSubitems.Contains(CurrentSubitem))
{
CurrentSubitem=可能的子项[0];
}
}
公众可观察到的收集可能性
{
获取{return\u possibleItems;}
专用设备
{
如果(等于(值,_possibleItems))返回;
_可能项=值;
OnPropertyChanged();
}
}
公共可观测收集可能的子项
{
获取{return _possibleSubitems;}
专用设备
{
如果(等于(值,_possibleSubitems))返回;
_可能项=值;
OnPropertyChanged();
}
}
公共字符串CurrentItem
{
获取{return\u currentItem;}
专用设备
{
if(value==\u currentItem)返回;
_currentItem=值;
OnPropertyChanged();
}
}
公共字符串子项
{
获取{return\u currentSubitem;}
设置
{
if(value==\u currentSubitem)返回;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
namespace WpfApplication1
{
public partial class MainWindow: Window, INotifyPropertyChanged
{
private string _currentItem;
private string _currentSubitem;
private ObservableCollection<string> _possibleItems;
private ObservableCollection<string> _possibleSubitems;
public MainWindow()
{
InitializeComponent();
LoadPossibleItems();
CurrentItem = PossibleItems[0];
UpdatePossibleSubItems();
DataContext = this;
CurrentItem = PossibleItems[0];
CurrentSubitem = PossibleSubitems[0];
PropertyChanged += (s, o) =>
{
if (o.PropertyName != "CurrentItem") return;
UpdatePossibleSubItems();
ValidateCurrentSubItem();
};
}
private void ValidateCurrentSubItem()
{
if (!PossibleSubitems.Contains(CurrentSubitem))
{
CurrentSubitem = PossibleSubitems[0];
}
}
public ObservableCollection<string> PossibleItems
{
get { return _possibleItems; }
private set
{
if (Equals(value, _possibleItems)) return;
_possibleItems = value;
OnPropertyChanged();
}
}
public ObservableCollection<string> PossibleSubitems
{
get { return _possibleSubitems; }
private set
{
if (Equals(value, _possibleSubitems)) return;
_possibleSubitems = value;
OnPropertyChanged();
}
}
public string CurrentItem
{
get { return _currentItem; }
private set
{
if (value == _currentItem) return;
_currentItem = value;
OnPropertyChanged();
}
}
public string CurrentSubitem
{
get { return _currentSubitem; }
set
{
if (value == _currentSubitem) return;
_currentSubitem = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void LoadPossibleItems()
{
PossibleItems = new ObservableCollection<string>
{
"Item 1",
"Item 2"
};
}
private void UpdatePossibleSubItems()
{
if (CurrentItem == PossibleItems[0])
{
PossibleSubitems = new ObservableCollection<string>
{
"Subitem A",
"Subitem B"
};
}
else if (CurrentItem == PossibleItems[1])
{
PossibleSubitems = new ObservableCollection<string>
{
"Subitem B",
"Subitem C"
};
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
private string _currentItem;
public string CurrentItem
{
get { return _currentItem; }
set
{
_currentItem = value;
// Changing the item changes the possible sub items
NotifyPropertyChanged("PossibleSubitems");
}
}
// List of potential Items, used to populate the options for the Subitems combo box
public ObservableCollection<string> PossibleSubitems { get; set; }
// Track the selected Item
private string _currentItem;
public string CurrentItem
{
get { return _currentItem; }
set
{
_currentItem = value;
// Changing the item changes the possible sub items
if (value == "Item 1")
PossibleSubitems = new ObservableCollection<string>() {"A","B"} ;
else
PossibleSubitems = new ObservableCollection<string>() { "C", "D" };
RaisePropertyChanged("CurrentItem");
RaisePropertyChanged("PossibleSubitems");
}
}