Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在wpf中将两个组合框绑定在一起_C#_Wpf_Mvvm_Binding_Combobox - Fatal编程技术网

C# 如何在wpf中将两个组合框绑定在一起

C# 如何在wpf中将两个组合框绑定在一起,c#,wpf,mvvm,binding,combobox,C#,Wpf,Mvvm,Binding,Combobox,我有两个组合框,一个包含“项目”列表,另一个包含“子项目”列表 子项列表取决于当前选定的项 我已经完成了大部分工作(通过将子项的ItemSource绑定到PossibleSubitems属性),但是问题是当我更改了项并且子项对于新项不再有效时。在这种情况下,我只想选择第一个有效的子项,但是我得到一个空白的组合框。注意,我认为类中的属性设置正确,但绑定似乎没有正确反映它 这里有一些代码来告诉你我在做什么。在这种情况下,我有: “项目1”,可以包含子项目A或子项目B,以及 “项目2”,可以有子项目B

我有两个组合框,一个包含“项目”列表,另一个包含“子项目”列表

子项列表取决于当前选定的项

我已经完成了大部分工作(通过将子项的ItemSource绑定到PossibleSubitems属性),但是问题是当我更改了项并且子项对于新项不再有效时。在这种情况下,我只想选择第一个有效的子项,但是我得到一个空白的组合框。注意,我认为类中的属性设置正确,但绑定似乎没有正确反映它

这里有一些代码来告诉你我在做什么。在这种情况下,我有: “项目1”,可以包含子项目A或子项目B,以及 “项目2”,可以有子项目B或子项目C

当我选择子项A时切换到项目2时,问题就出现了

XAML


代码隐藏:

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");
    }
}