2012-11-27 44 views
1

我已经搜索和搜索,但无法获得正确且有用的答案。将ViewModel中包含的ObservableCollection绑定到ListView

我有一个MainWindow wpf窗口。它的DataContext被设置为它的ViewModel。

我有被绑定到视图模型一个ObservableCollection一个ListView:

 <ListView Grid.Row="1" Grid.Column="0" Margin="2" Name="sources_ListView" Grid.RowSpan="1" ItemsSource="{Binding Path=Sources}"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Width="290" Header="Name" 
            DisplayMemberBinding="{Binding Path=OriginalPath}"/> 
        <GridViewColumn Width="80" Header="Type" 
            DisplayMemberBinding="{Binding Path=Type}"/> 
       </GridView> 
      </ListView.View> 
     </ListView> 

RelayCommand:

 public ICommand BrowseFileFolderCommand 
     { 
      get 
      { 
       if (_browseFileFolderCommand == null) 
       { 
        _browseFileFolderCommand = new RelayCommand(o => 
           { 
            _sources.Add(new SourceItem(selectedPath, new DirectoryInfo(selectedPath))); 
           }, null); 
       } 
       return _browseFileFolderCommand; 
      } 
     } 

现在很明显的lambda函数做什么,不会在现实世界因为我已经脱离了上下文,但接受它将SourceItem添加到ObservableCollection _sources并且存在获取_sources的公共源的事实。我也制作了ObservableCollection使用的类型INotifyChangedProperty。

当我使用RelayCommand是一个按钮,它将一个源添加到ObservableCollection中时,ListView不会更新?

感谢所有帮助

编辑SourceItem:

public class SourceItem : ISourceItem, INotifyPropertyChanged 
{ 
    DirectoryInfo _sourceFolder; 
    public DirectoryInfo SourceFolder { get { return _sourceFolder; } private set { _sourceFolder = value; } } 

    FileInfo _sourceFile; 
    public FileInfo SourceFiles { get { return _sourceFile; } private set { _sourceFile = value; } } 

    string _originalPath; 
    public string OriginalPath { get { return _originalPath; } private set { _originalPath = value; OnPropertyChanged("OriginalPath"); } } 

    bool _isFolder; 
    public bool IsFolder { get { return _isFolder; } } 

    // display friendly property of IsFolder 
    public string Type { get { return _isFolder == true ? "Folder" : "File"; } } 

    public SourceItem(string originalPath, DirectoryInfo sourceFolder) 
    { 
     _originalPath = originalPath; 
     _sourceFolder = sourceFolder; 
     _sourceFile = null; 

     _isFolder = true; 
    } 

    public SourceItem(string originalPath, FileInfo sourceFile) 
    { 
     _originalPath = originalPath; 
     _sourceFile = sourceFile; 
     _sourceFolder = null; 

     _isFolder = false; 
    } 



    #region INotifyPropertyChanged Members 

    /// <summary> 
    /// Raised when a property on this object has a new value. 
    /// </summary> 
    public event PropertyChangedEventHandler PropertyChanged; 

    /// <summary> 
    /// Raises this object's PropertyChanged event. 
    /// </summary> 
    /// <param name="propertyName">The property that has a new value.</param> 
    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     this.VerifyPropertyName(propertyName); 

     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      var e = new PropertyChangedEventArgs(propertyName); 
      handler(this, e); 
     } 
    } 

    #endregion // INotifyPropertyChanged Members 

    #region Debugging Aides 

    /// <summary> 
    /// Warns the developer if this object does not have 
    /// a public property with the specified name. This 
    /// method does not exist in a Release build. 
    /// </summary> 
    [Conditional("DEBUG")] 
    [DebuggerStepThrough] 
    public void VerifyPropertyName(string propertyName) 
    { 
     // Verify that the property name matches a real. 
     // public, instance property on this object 
     if (TypeDescriptor.GetProperties(this)[propertyName] == null) 
     { 
      string msg = String.Format("Invalid property name: {0}", propertyName); 

      if (this.ThrowOnInvalidPropertyName) 
       throw new Exception(msg); 
      else 
       Debug.Fail(msg); 
     } 
    } 

    /// <summary> 
    /// Returns whether an exception is thrown, or if a Debug.Fail() is used 
    /// when an invalid property name is passed to the VerifyPropertyName method. 
    /// The default value is false, but subclasses used by unit tests might 
    /// override this property's getter to return true. 
    /// </summary> 
    protected virtual bool ThrowOnInvalidPropertyName { get; private set; } 

    #endregion 
} 
+0

1 - 发布您的Observablecollection定义。 2 - 你看到VS调试输出的任何绑定错误? –

+0

1.完成,2.没有错误出现 –

回答

1

使用属性的公版,增加了新的项目

Sources.Add(new SourceItem(selectedPath, new DirectoryInfo(selectedPath))); 

您目前加入该项目的私人(_sources),而您的用户界面绑定到该属性的公共版本(Sources),因此您的用户界面不会获得CollectionChanged通知财产的私人版本引发,所以不知道它需要更新。

另一种方法是手动简单地为您的课程提高PropertyChanged事件以通知UI进行更新。这通常是我想要在同一时间向我的集合中添加大量项目时所做的工作,但只需要更新一次UI。

_sources.Add(new SourceItem(selectedPath, new DirectoryInfo(selectedPath))); 
RaisePropertyChanged("Sources"); 
+0

但是实例化呢? –

+0

@ No1_Melman我不知道我明白你在问什么。实例化呢?通常,我的ObservableCollections是在构造函数或属性的get方法中创建的(如果该属性的私有版本为null) – Rachel

+0

RaisePropertyChanged来自哪里? –

相关问题