Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.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# 使用ObservableCollection(C,WPF)实现Onpropertychanged_C#_Wpf_Xaml_Observablecollection_Propertychanged - Fatal编程技术网

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

C# 使用ObservableCollection(C,WPF)实现Onpropertychanged,c#,wpf,xaml,observablecollection,propertychanged,C#,Wpf,Xaml,Observablecollection,Propertychanged,我有带有项目列表的组合框: MainWindow.xaml 元素添加到下面的方法中,工作正常: MainViewModel.cs 注意-我已安装PropertyChanged.Fody 现在,我已将第二个ComboBox任务列表添加到xaml中: <ComboBox ItemsSource="{Binding Path=TaskList}" IsSynchronizedWithCurrentItem="True" /> 此处的列表应根据项目列表中的选定项创建。方法基本相同,只有一个

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

MainWindow.xaml

元素添加到下面的方法中,工作正常:

MainViewModel.cs

注意-我已安装PropertyChanged.Fody

现在,我已将第二个ComboBox任务列表添加到xaml中:

<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)
       }
 }   
现在我想把它添加到我的MVVM中


问题是:何时以及如何运行GetTask?不应在PropertyChanged上实现ObservableCollection任务列表的内部设置?

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

如果您使用的是隐藏代码,则可以将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>
我还为SelectedProject添加了一个属性,绑定到项目组合框的SelectedItem


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

更改组合框如下:

       <ComboBox ItemsSource="{Binding Path=ProjectList}" 
                 IsSynchronizedWithCurrentItem="True"
                 SelectedItem="{Binding SelectedProject}" >                
       </ComboBox>
选择Project时,下一个cb应加载run taskList

然后,您应该将ComboBox的SelectedItem属性绑定到字符串源属性,并在该属性的setter中调用GetTask方法,例如:

    private string _selectedProject;
    public string SelectedProject
    {
        get { return _selectedProject; }
        set
        {
            _selectedProject = value;
            GetTask(_selectedProject);
        }
    }
…或在选择更改时调用命令:从setter:

set
{
    _selectedProject = value;
    YourCommand.Execute(null);
}
…或使用

属性不应该在其setter中真正启动异步后台操作。有关这方面的更多信息,请参阅我的回答:


你能澄清你的问题吗?我不知道你的意思是什么,而不是内部设置应该实现ProjyType?我认为你应该查看一个主细节视图,并考虑将你的项目字符串更改为一个对象,它拥有任务列表,然后你可以绑定到它,而不是把所有东西都放在一个VIEW模型中。您的意思是,您是否应该为ObservableCollection实现一个setter,从而更改InotifyProperty?那么,不,我不这样做。调用。清除并再次添加项目。@4est:PropertyChanged.Fody与此有什么关系?当添加和删除项时,ObservableCollection将向UI引发事件。这与INotifyPropertyChanged无关。当你选择项目时,下一个CB应该加载TaskList:如果Fody不需要,你是什么意思?->我需要将选择加到CXL中吗?不,只绑定到源属性:我得到INF来考虑插入等待……当我等待GETTASKSLEDTED项目时,我得到了只能等待的结果。在异步方法中,这就是为什么不应该在其setter中启动异步后台操作。你看了我提供的链接了吗?好的,我已经更改了,但是我得到了所有的任务列表,不仅仅是针对选定的项目…我认为我运行GetTask的位置是错误的
       <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);
}
    private string _selectedProject;
    public string SelectedProject
    {
        get { return _selectedProject; }
        set
        {
            _selectedProject = value;
            GetTask(_selectedProject);
        }
    }
set
{
    _selectedProject = value;
    YourCommand.Execute(null);
}