我在XAML中定义了一个列表框:
<ListBox x:Name="directoryList"
MinHeight="100"
Grid.Row="0"
ItemsSource="{Binding Path=SelectedDirectories}"/>
SelectedDirectories是类型为List<DirectoryInfo>
作为列表框的datacontext的类实现了INotifyPropertyChanged。当集合更改时,项目会成功添加到列表中,但是在我通过调整列表框重新强制重绘之前,显示不会更新。
任何想法为什么?
编辑:INotifyPropertyChanged实施
public class FileScannerPresenter : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private FileScanner _FileScanner;
public FileScannerPresenter()
{
this._FileScanner = new FileScanner();
}
public List<DirectoryInfo> SelectedDirectories
{
get
{
return _FileScanner.Directories;
}
}
public void AddDirectory(string path)
{
this._FileScanner.AddDirectory(path);
OnPropertyChanged("SelectedDirectories");
}
public void OnPropertyChanged(string property)
{
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
答案 0 :(得分:3)
尝试
ObservableCollection<DirectoryInfo>
相反 - 您无缘无故地触发整个ListBox的刷新,并且您不需要使您的托管类实现INotifyPropertyChanged - 它可以很容易地只是窗口的属性。关键是永远不要将属性设置为新实例。所以:
class SomeWindow : Window {
public ObservableCollection<DirectoryInfo> SelectedDirectories {get; private set;}
SomeWindow() { SelectedDirectories = new ObservableCollection<DirectoryInfo>(); }
public void AddDirectory(string path) {
SelectedDirectories.Add(new DirectoryInfo(path));
}
}
如果您最终使用该FileScanner类,则需要实现INotifyCollectionChanged - 这样,ListBox知道要动态添加/删除的内容。
答案 1 :(得分:0)
(请参阅下面的更新)。 WPF似乎工作正常。我把你的代码放到一个新项目中。 每当我单击按钮调用AddDirectory时,列表框都会更新。您不应再需要更改代码。 问题似乎是别的......你的UI中有多个线程吗?
我没有FileScanner类型。所以我创建了一个假人,如下所示。
public class FileScanner
{
string _path;
public FileScanner()
{ _path = @"c:\"; }
public List<DirectoryInfo> Directories
{
get
{
return Directory.GetDirectories(_path).Select(path => new DirectoryInfo(path)).ToList();
}
}
internal void AddDirectory(string path)
{ _path = path; }
}
对FileScannerPresenter类没有任何更改。或者你的列表框XAML。我创建了一个带有DockPanel的Window,其中包含列表框,文本框和按钮。
更新:保罗贝茨是对的。它的工作原理是因为我每次都从Bound属性返回一个新列表。与列表的数据绑定总是让我感到困惑。 通过更多的修补,简单的方法是:
ObservableCollection<DirectoryInfo>
(为您实现INotifyCollectionChanged
)。一直更改所有签名以返回此类型而不是List<DirectoryInfo>
FileScanner和FileScannerPresenter本身不必实现任何INotifyXXX接口。
// in FileScanner class def
public ObservableCollection<DirectoryInfo> Directories
{
get
{ return _DirList; }
}
internal void AddDirectory(string path)
{
_path = path;
//var newItems = Directory.GetDirectories(_path).Select(thePath => new DirectoryInfo(thePath)).ToList();
//_DirList.Concat( newItems ); -- doesn't work for some reason.
foreach (var info in Directory.GetDirectories(_path).Select(thePath => new DirectoryInfo(thePath)).ToList())
{
_DirList.Add(info);
}
}