WPF组合框没有绑定更改

时间:2015-04-07 14:47:05

标签: c# .net wpf combobox

我有3个组合框

<Grid>
   <ComboBox Name="cbo1" SelectionChanged="OnComboBoxChanged" />
   <ComboBox Name="cbo2" SelectionChanged="OnComboBoxChanged"/>
   <ComboBox Name="cbo3" SelectionChanged="OnComboBoxChanged" />

组合框列表是{a,b,c,d} 所以如果&#34; b&#34;在第一个框中选择,然后下拉列表不应该有b,如果第二个设置为a,则需要更新{a,c,d},然后最后一个需要{c,d}。如果他们回去改变我们需要相应更新列表。我添加了一个oncomboboxchanged事件,但当我将项目源设置为新列表时,它没有更新组合框。

private List<string> comboList = new List<string>();
string[] defaultParam = { "A", "B", "C", "D" };

public MainWindow()
{   
       InitializeComponent();
       foreach(string s in defaultParam)
       {
           LoadCombo(s);
       } 

}
public void LoadCombo(string name)
{
   comboList.Add(name); 
   cbo1.ItemsSource = comboList;
   cbo2.ItemsSource = comboList;
   cbo3.ItemsSource = comboList;
}
private void OnComboBoxChanged(object sender,SelectionChangedEventArgs e)
{
   var combo = sender as ComboBox;
   string oldval = combo.Text;
   string id = combo.Name;
   string itemSel = (sender as ComboBox).SelectedItem.ToString();
   comboList.Remove(itemSel);
   //add old value only if it is not empty
   if (!string.IsNullOrEmpty(oldval))
   {
      comboList.Add(oldval);
   }
   combo.ItemsSource = comboList;
   ComboBox[] comboNameLst = {cbo1,cbo2,cbo3 }; 
   foreach (ComboBox cbo in comboNameLst)
   {
       if (id != cbo.Name)
       {
          if (cbo.SelectedItem == null)
          {
              cbo.ItemsSource = comboList;
          }
          else if (cbo.SelectedItem != null)
          {
             string tempitemsel = cbo.SelectedItem.ToString();
             comboList.Add(tempitemsel);
             cbo.ItemsSource = comboList;
             comboList.Remove(tempitemsel);
          }
       }
   }
}

所以cbo.ItemSource没有做任何事情,我是否需要以不同的方式做任何事情,所以我看到了更新。

2 个答案:

答案 0 :(得分:3)

  1. 您需要在XAML中使用绑定,而不是在后面的代码中设置ItemsSource。数据绑定SelectedItem

     <Grid>
         <ComboBox ItemsSource="{Binding DefaultList}" SelectedItem="{Binding SelectedItem_Cob1}"/>
         <ComboBox ItemsSource="{Binding FilteredListA}" SelectedItem="{Binding SelectedItem_Cob2}"/>
         <ComboBox ItemsSource="{Binding FilteredListB}" SelectedItem="{Binding SelectedItem_Cob3}"/>
     </Grid>
    
  2. 在您的代码中,您需要实现INotifyPropertyChanged;将您的相关ItemsSources和SlectedItems定义为属性;并将Windows的DataContext设置为您自己的代码(您应该使用MVVM模式但稍后可能会担心):

    using System.ComponentModel;
    public partial class MainWindow: INotifyPropertyChanged
    { 
        string[] defaultParam = { "A", "B", "C", "D" };
        private string _selecteditem_cob1;
        private string _selecteditem_cob2;
        private string _selecteditem_cob3;
    
        public List<string> DefaultList
        {
            get { return defaultParam.ToList(); }
        }
    
        public string SelectedItem_Cob1
        {
            get { return _selecteditem_cob1; }
            set
            {
                if (_selecteditem_cob1 != value)
                {
                    _selecteditem_cob1 = value;
                    RaisePropertyChanged("SelectedItem_Cob1");
                    RaisePropertyChanged("FilteredListA");
                    RaisePropertyChanged("FilteredListB");
                }
            }
        }
    
        public string SelectedItem_Cob2
        {
            get { return _selecteditem_cob2; }
            set
            {
                if (_selecteditem_cob2 != value)
                {
                    _selecteditem_cob2 = value;
                    RaisePropertyChanged("SelectedItem_Cob2");
                    RaisePropertyChanged("FilteredListB");
                }
            }
        }
    
        public string SelectedItem_Cob3
        {
            get { return _selecteditem_cob3; }
            set
            {
                if (_selecteditem_cob3 != value)
                {
                    _selecteditem_cob3 = value;
                    RaisePropertyChanged("SelectedItem_Cob3");
                }
            }
        }
    
        public List<string> FilteredListA
        {
            get { return defaultParam.ToList().Where(a=>a!=SelectedItem_Cob1).ToList(); }
        }
        public List<string> FilteredListB
        {
            get { return FilteredListA.Where(a => a != SelectedItem_Cob2).ToList(); }
        }
        public MainWindow()
        {
    
            InitializeComponent();  
            this.DataContext=this;          
        }
    
        //Implementation for INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, e);
            }
        }
    
        protected void RaisePropertyChanged(String propertyName)
        {
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }
    }
    
  3. 结果:

      

    三个组合框将在初始阶段显示 A,B,C,D 。和   然后,如果用户选择cbo2,则cbo3将仅显示   动态过滤结果。

         

    我意识到这不是你想要的100%(感谢@TheodosiusVonRichthofen),但我觉得你仍然可以使用它,并且能够轻松修改它以满足你的需要。

答案 1 :(得分:1)

此外,包含组合框项的列表应该是ObservableCollection而不是List。通过使其成为ObservableCollection,当您在列表中添加/删除/更改项目时,将更新组合框项目。