除非onPropertyChanged已触发,否则将可观察集合绑定到列表框项源不会更新

时间:2013-04-04 15:10:49

标签: c# wpf mvvm observablecollection

我正在尝试使用列表框显示上传文件的文件名列表。我有按钮来上传,打开和删除列表框中的文件。我正在使用mvvm模式并将itemsource绑定到一个可观察的集合。当我修改集合(即:upload或del)时,列表框不会刷新以反映集合更改时的更改。我确信我实现这一点的方式很糟糕。在这一点上,我完全混淆了可观察集合如何通知变化。以下是我的代码:

 <ListBox x:Name="Listbox1"    
          SelectedItem="{Binding SelectedFile}" 
          SelectedIndex="{Binding SelectedIndexNum}"
          ItemsSource="{Binding Path=FileNames, UpdateSourceTrigger=PropertyChanged}">                            
 </ListBox>
 <Button Content="UploadFile" 
         Command="{Binding Path=UploadFileCommand}" 
 </Button>

 <Button Content="Delete File" 
         Command="{Binding Path=DeleteFileCommand}" 
 </Button>

视图模型属性:

 public ObservableCollection<string> FileNames
    {
        get
        {
            if (this.SomeDataStruc.UploadedFileDataCollection == null || this.SomeDataStruc.UploadedFileDataCollection .Count() <= 0)
            {
                return new ObservableCollection<string>();
            }
            else
            {
                var uploadedFileList = this.SomeDataStruc.UploadedFileDataCollection .Where(r => r.Id == this.SomeDataStruc.Id);
                var filenames = new ObservableCollection<string>(uploadedFileList.Select(c => c.FileName));//.ToList();
                return filenames;
            }
        }          
    }

请注意,SomeDataStruc有一个可观察的集合。这个UploadedFileData有很多字段,我只在列表框中显示文件名。

 private void DeleteReport(object parameter)
    {
        this.UploadedFileDataCollection[_selectedIndex].Status = DataStatusEnum.Deleted;

        this.SomeDataStruc.UploadedFileDataCollection.RemoveAt(_selectedIndex);


        this.OnPropertyChanged("FileNames"); // i need to do this...Listbox doesnt update without this.


    }

我做错了什么我应该处理collectionchanged事件吗?如果是这样的话?不是可观察的收集点......它自己通知了吗?

我检查过很多类似的话题。但这似乎并不能解决我的困惑。请帮帮我。

2 个答案:

答案 0 :(得分:2)

您的问题是FileNames属性总是返回一个新的ObservableCollection。

如果你有这样的代码:

private ObservableCollection<string> _fileNames;

public ObservableCollection<string> FileNames
{
    get
    {
        if(_fileNames == null) 
        { 
            _fileNames = new ObservableCollection<string>(); 
        }
        return _fileNames;
    }
}

然后,对FileNames集合的任何更改都会导致通知和UI更新。

e.g。

private void LoadFileNames()
{
    FileNames.Clear();
    foreach( ... ) 
    { 
        FileNames.Add(...);  // collection changed notification here
    }
}

由于每次使用FileNames时都会更改集合(效率低下),因此需要调用this.OnPropertyChanged("FileNames");告诉UI整个集合已被替换。

答案 1 :(得分:0)

这是正确的行为,因为你不从FileNames中删除任何东西,只是从UploadedFileDataCollection这是一个常规列表。所以很明显你需要提高propertyChanged以便根据UploadedFileDataCollection中剩余的项目重新创建FileNames列表