1

我已经搜索和搜索,但无法获得正确、有用的答案。

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

我有一个绑定到 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>

中继命令:

        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 的 Public Sources 的事实。我还使 ObservableCollection 采用的类型使用 INotifyChangedProperty。

当我使用按钮内的 RelayCommand 将源添加到 ObservableCollection 时,ListView 不会更新?

谢谢你的帮助

编辑源项:

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
}
4

1 回答 1

1

使用公共版本的属性添加新项目

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

您当前正在将项目添加到属性的私有版本 ( _sources),而您的 UI 绑定到属性的公共版本 ( Sources),因此您的 UI 不会收到CollectionChanged属性的私有版本引发的通知,因此知道它需要更新。

另一种方法是简单地手动为您的类引发PropertyChanged事件以告诉 UI 进行更新。当我想同时向我的收藏中添加大量项目时,通常会这样做,但只更新一次 UI。

_sources.Add(new SourceItem(selectedPath, new DirectoryInfo(selectedPath)));
RaisePropertyChanged("Sources");
于 2012-11-27T17:36:29.703 回答