2012-11-27 73 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來自哪裏? –

相關問題