【问题标题】:binding observable collection to listbox item source doesnt update unless onPropertyChanged fired除非 onPropertyChanged 被触发,否则将可观察集合绑定到列表框项源不会更新
【发布时间】:2013-04-04 15:10:49
【问题描述】:

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

 <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 事件吗?如果是,为什么?这不是可观察收集的重点......它自己通知吗?

我检查了许多类似的主题。但这似乎并没有消除我的困惑。请帮帮我。

【问题讨论】:

  • 您的视图模型类应该实现 INotifyPropertyChanged。

标签: c# wpf mvvm observablecollection


【解决方案1】:

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

如果你有这样的代码:

private ObservableCollection<string> _fileNames;

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

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

例如

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

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

【讨论】:

  • 谢谢!这清除了我脑海中的很多废话!有时一个人可能对你面前的事情视而不见! :(
  • 在尝试从非 UI 线程执行 Clear() 或 Add() 时,这不会抛出 NotSupportedException 吗?
【解决方案2】:

这是正确的行为,因为您不会从 FileNames 中删除任何内容,而只是从作为常规列表的 UploadedFileDataCollection 中删除。很明显,您需要提高 propertyChanged 以使 UI 根据 UploadedFileDataCollection 中的剩余项目重新创建 FileNames 列表

【讨论】:

    猜你喜欢
    • 2011-02-16
    • 1970-01-01
    • 2013-05-21
    • 2020-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多