Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.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 MVVM在另一个组合框的PropertyChanged上填充组合框_C#_Wpf_Mvvm - Fatal编程技术网

C# WPF MVVM在另一个组合框的PropertyChanged上填充组合框

C# WPF MVVM在另一个组合框的PropertyChanged上填充组合框,c#,wpf,mvvm,C#,Wpf,Mvvm,我想在combobox1选择更改事件后填充Combox2 下面是我的XAML的一些部分: <ComboBox Name="cmbWorkcode" ItemsSource="{Binding Workcodes}" DisplayMemberPath="WorkcodeName" SelectedValuePath="WorkcodeID" SelectedValue="{Binding Path=WorkcodeId,

我想在combobox1选择更改事件后填充Combox2

下面是我的XAML的一些部分:

<ComboBox Name="cmbWorkcode"
        ItemsSource="{Binding Workcodes}" 
        DisplayMemberPath="WorkcodeName" 
        SelectedValuePath="WorkcodeID" 
        SelectedValue="{Binding Path=WorkcodeId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<ComboBox Name="cmbProcess" 
        ItemsSource="{Binding Processes}"
        DisplayMemberPath="ProcessName" SelectedValuePath="ProcessId"
        SelectedValue="{Binding Path=ProcessId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

最初,第二个组合框为空,在选择第一个组合框时,仅更改了流程

 private int _workcodeId;
 public int WorkcodeId
 {
   get { return _workcodeId; }
   set
   {
      _workcodeId = value;
      OnPropertyChanged("WorkcodeId");
      if(WorkcodeID>0) PopulateProcess();
   }
}

我可以理解您希望在下一个组合框中填充基于上一个值的数据。因为我没有你这种类型的类,我将给出一个简单的例子

class ItemListViewModel<T> : INotifyPropertyChanged where T : class
{
    private T _item;
    private ObservableCollection<T> _items;

    public ItemListViewModel()
    {
        _items = new ObservableCollection<T>();
        _item = null;
    }

    public void SetItems(IEnumerable<T> items)
    {
        Items = new ObservableCollection<T>(items);
        SelectedItem = null; 
    }

    public ObservableCollection<T> Items
    {
        get { return _items; }
        private set
        {
            _items = value;
            RaisePropertyChanged("Items");
        }
    }

    public T SelectedItem
    {
        get { return _item; }
        set
        {
            _item = value;
            RaisePropertyChanged("SelectedItem");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
class ItemListViewModel:INotifyPropertyChanged其中T:class
{
私人信托基金项目;
私人可观测收集项目;
public ItemListViewModel()
{
_items=新的ObservableCollection();
_item=null;
}
公共无效集合项(IEnumerable项)
{
项目=新的可观测集合(项目);
SelectedItem=null;
}
公共可观测收集项目
{
获取{return\u items;}
专用设备
{
_项目=价值;
增加财产变更(“项目”);
}
}
公共T选择项
{
获取{return\u item;}
设置
{
_项目=价值;
RaisePropertyChanged(“SelectedItem”);
}
}
公共事件属性更改事件处理程序属性更改;
私有void RaisePropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
然后将主viewmodel绑定到视图的DataContext。让加载方法执行您想要的操作

class MyViewModel : INotifyPropertyChanged
{
    public MyViewModel()
    {
        First = new ItemListViewModel<string>();
        Second = new ItemListViewModel<string>();
        Third = new ItemListViewModel<string>();

        First.PropertyChanged += (s, e) => Update(e.PropertyName, First, Second, LoadSecond);
        Second.PropertyChanged += (s, e) => Update(e.PropertyName, Second, Third, LoadThird);

        LoadFirst();
    }

    public ItemListViewModel<string> First { get; set; }
    public ItemListViewModel<string> Second { get; set; }
    public ItemListViewModel<string> Third { get; set; }

    private void LoadFirst()
    {
        First.SetItems(new List<string> { "One", "Two", "Three" });
    }
    private void LoadSecond()
    {
        Second.SetItems(new List<string> { "First", "Second", "Third" });
    }
    private void LoadThird()
    {
         Third.SetItems(new List<string> { "Firsty", "Secondly", "Thirdly" });
    }

    private void Update<T0, T1>(string propertyName, ItemListViewModel<T0> parent, ItemListViewModel<T1> child, Action loadAction)
        where T0 : class
        where T1 : class
    {
        if (propertyName == "SelectedItem")
        {
            if (parent.SelectedItem == null)
            {
                child.SetItems(Enumerable.Empty<T1>());
            }
            else
            {
                loadAction();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}
类MyViewModel:INotifyPropertyChanged
{
公共MyViewModel()
{
First=新的ItemListViewModel();
第二个=新的ItemListViewModel();
第三个=新的ItemListViewModel();
First.PropertyChanged+=(s,e)=>Update(e.PropertyName,First,Second,LoadSecond);
Second.PropertyChanged+=(s,e)=>Update(e.PropertyName,Second,Third,LoadThird);
LoadFirst();
}
public ItemListViewModel First{get;set;}
public ItemListViewModel第二个{get;set;}
public ItemListViewModel第三个{get;set;}
私有void LoadFirst()
{
第一.集合项目(新的清单{“一”、“二”、“三”});
}
私有void LoadSecond()
{
第二.集合项目(新列表{“第一”、“第二”、“第三”});
}
私有void LoadThird()
{
第三,集合项目(新列表{“第一”、“第二”、“第三”});
}
私有无效更新(字符串propertyName、ItemListViewModel父项、ItemListViewModel子项、Action loadAction)
哪里T0:班级
其中T1:class
{
如果(propertyName==“SelectedItem”)
{
如果(parent.SelectedItem==null)
{
SetItems(Enumerable.Empty());
}
其他的
{
loadAction();
}
}
}
公共事件属性更改事件处理程序属性更改;
}
在XAML中

    <ComboBox ItemsSource="{Binding First.Items}" SelectedItem="{Binding First.SelectedItem}" />
    <ComboBox ItemsSource="{Binding Second.Items}" SelectedItem="{Binding Second.SelectedItem}" />
    <ComboBox ItemsSource="{Binding Third.Items}" SelectedItem="{Binding Third.SelectedItem}" />

问题就在这里

<ComboBox Name="cmbWorkcode"
    ItemsSource="{Binding Workcodes}" 
    DisplayMemberPath="WorkcodeName" 
    SelectedValuePath="WorkcodeId" 
    SelectedValue="{Binding Path=WorkcodeId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

最初获取processcollection并将其存储在临时集合中,然后根据所选的工作代码填充第二个组合框。@jomsk1e您的Process类是否实现了INPC?如果没有,我相信您必须引发CollectionChanged事件,以便WPF知道您集合中的项目已更改。(如果实际集合本身已更改,但其中的项目未更改,则当前代码将通知更改)。查看此答案了解详细信息@编程失败,请查看我的编辑,我添加了用于实现INotifyPropertyChanged的类。能否显示您的工作代码类就是它!谢谢我是个傻瓜(这是个好机会:)。还有一件事,当我们使用ObservableCollection时,我们不需要通知,因此dnt需要创建支持字段。只有公共ObservableCollection进程{get;set;}可以工作。尽管您需要在构造函数中初始化它。感谢Sajeetharan的时间,您的示例可能也会帮助其他人。:)
    <ComboBox ItemsSource="{Binding First.Items}" SelectedItem="{Binding First.SelectedItem}" />
    <ComboBox ItemsSource="{Binding Second.Items}" SelectedItem="{Binding Second.SelectedItem}" />
    <ComboBox ItemsSource="{Binding Third.Items}" SelectedItem="{Binding Third.SelectedItem}" />
<ComboBox Name="cmbWorkcode"
    ItemsSource="{Binding Workcodes}" 
    DisplayMemberPath="WorkcodeName" 
    SelectedValuePath="WorkcodeId" 
    SelectedValue="{Binding Path=WorkcodeId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
public int WorkcodeId
{
   get { return _workcodeId; }
   set
   {
   if(_workcodeId !=value)
  {
    _workcodeId = value;
    OnPropertyChanged("WorkcodeId");
    PopulateProcess();
  }
 }
}