代码之家  ›  专栏  ›  技术社区  ›  4est

使用ObservableCollection(C#,WPF)实现Onpropertychanged

  •  -1
  • 4est  · 技术社区  · 6 年前

    我有带“项目列表”的组合框:

    <ComboBox ItemsSource="{Binding Path=ProjectList}" IsSynchronizedWithCurrentItem="True" />
    

    MainViewModel.cs

    [AddINotifyPropertyChangedInterface]
    public class MainViewModel{
    
     public ObservableCollection<string> ProjectList { get; internal set; } 
      = new ObservableCollection<string>(); 
    
      public async Task GetProjects(){
      ...
       foreach (AItem item in....)
       {
         ProjectList.Add(item.name)
       }
     }    
    }
    

    注意-我已经安装了“PropertyChanged.Fody”。

    <ComboBox ItemsSource="{Binding Path=TaskList}" IsSynchronizedWithCurrentItem="True" />
    

    这里的列表应该基于“项目列表”中的选定项目创建。方法基本相同,只有一个参数:

    public ObservableCollection<string> TaskList { get; internal set; } 
     = new ObservableCollection<string>();
    
    public async Task GetTask(string projectId = ""){
          ...
           foreach (AItem item in....)
           {
             TaskList.Add(item.name2)
           }
     }   
    

    问题是 :何时以及如何运行GetTask()?而不是“内部设置” 可观察收集任务列表 应该实现“onpropertychanged”?

    3 回复  |  直到 6 年前
        1
  •  1
  •   mm8    6 年前

    当您选择Project时,下一个cb应该加载(运行)taskList

    SelectedItem ComboBox 到字符串源属性并调用 GetTask 方法,例如:

        private string _selectedProject;
        public string SelectedProject
        {
            get { return _selectedProject; }
            set
            {
                _selectedProject = value;
                GetTask(_selectedProject);
            }
        }
    

    set
    {
        _selectedProject = value;
        YourCommand.Execute(null);
    }
    

    …或者使用 interaction trigger .

    Is wrong to invoke an async method from property setter in WPF view model?

        2
  •  0
  •   Robin Bennett    6 年前

    您需要在项目列表组合框的选定项更改时激发的事件。

    如果使用的是代码隐藏,只需将SelectionChanged属性设置为指向函数。不过,看起来您使用的是MVVM,因此需要向组合框中添加一个交互触发器、一个用于调用触发器的命令和一个用于调用命令的方法。

    将此命名空间添加到窗口:

    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    

    更改组合框以包含触发器并公开SelectedItem

               <ComboBox ItemsSource="{Binding Path=ProjectList}" 
                         IsSynchronizedWithCurrentItem="True"
                         SelectedItem="{Binding SelectedProject}" >
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="SelectionChanged">
                            <i:InvokeCommandAction Command="{Binding ReloadTasksCommand}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </ComboBox>
    

    private ICommand reloadTasks;
    public ICommand ReloadTasksCommand => this.reloadTasks?? (this.reloadTasks= new RelayCommand(this.ReloadTasks));
    
    public string SelectedProject{ get; set; }
    
    private void ReloadTasks()
    {
        GetTasks(this.SelectedProject);
    }
    

    我还为SelectedProject添加了一个属性,绑定到项目组合框的SelectedItem。

    RelayCommand位于GalaSoft.MvvmLight.CommandWpf库中。还有其他的,这正是我所用的。

        3
  •  0
  •   lokij    6 年前

           <ComboBox ItemsSource="{Binding Path=ProjectList}" 
                     IsSynchronizedWithCurrentItem="True"
                     SelectedItem="{Binding SelectedProject}" >                
           </ComboBox>
    

    private string _selectedObject;
    public string SelectedObject
    {
        get { return _selectedObject; }
        set
        {
            _selectedObject = value;
            //OnPropertyChanged(); -- INotifyPropertyChanged no need if Fody
            ReloadTasks();
        }
    }
    
    private void ReloadTasks()
    {
        GetTasks(SelectedProject);
    }