我进行了搜索和搜索,但无法获得正确有用的答案。
我有一个MainWindow wpf窗口。它的DataContext设置为ViewModel。
我有一个ListView,绑定到ViewModel中的ObservableCollection:
<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不会更新?
感谢您的帮助
EDIT 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)
使用该属性的公共版本添加新项目
Sources.Add(new SourceItem(selectedPath, new DirectoryInfo(selectedPath)));
您当前正在将该项目添加到您的媒体资源的私有版本(_sources
),而您的用户界面则绑定到该属性的公开版本(Sources
),因此您的用户界面无法获取<{1}}通知属性的私有版本引发,因此不知道它需要更新。
另一种方法是手动为您的类提升CollectionChanged
事件,以告知UI更新。这通常是我想要同时向我的集合添加大量项目时所做的,但只有UI更新一次。
PropertyChanged