WPF列表框未重新绘制

WPF列表框未重新绘制,wpf,listbox,redraw,Wpf,Listbox,Redraw,我在XAML中定义了一个列表框: <ListBox x:Name="directoryList" MinHeight="100" Grid.Row="0" ItemsSource="{Binding Path=SelectedDirectories}"/> SelectedDirectories是List DataContext上的一个属性,类型为List listbox的d

我在XAML中定义了一个列表框:

<ListBox x:Name="directoryList"
                 MinHeight="100" 
                 Grid.Row="0"
                 ItemsSource="{Binding Path=SelectedDirectories}"/>

SelectedDirectories是List DataContext上的一个属性,类型为
List

listbox的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));
            }
        }
    }
公共类FileScanerPresenter:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
专用文件扫描程序\u文件扫描程序;
公共文件CannerPresenter()
{
这是。_FileScanner=newfilescanner();
}
公共选定目录列表
{
得到
{
返回_FileScanner.Directories;
}
}
public void AddDirectory(字符串路径)
{
此.u FileScanner.AddDirectory(路径);
关于财产变更(“选定董事”);
}
公共void OnPropertyChanged(字符串属性)
{
if(this.PropertyChanged!=null)
{
PropertyChanged(此,新PropertyChangedEventArgs(property));
}
}
}
试试看

observedcollection
相反,您会无缘无故地触发整个列表框的刷新,并且不需要让宿主类实现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));
    }
}
class SomeWindow:Window{
公共ObservableCollection SelectedDirectories{get;private set;}
SomeWindow(){SelectedDirectories=new ObservableCollection();}
public void AddDirectory(字符串路径){
添加(新目录信息(路径));
}
}
如果最终使用该FileScaner类,则需要实现INotifyCollectionChanged,这样,列表框就知道动态添加/删除哪些内容。

试试看

observedcollection
相反,您会无缘无故地触发整个列表框的刷新,并且不需要让宿主类实现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));
    }
}
class SomeWindow:Window{
公共ObservableCollection SelectedDirectories{get;private set;}
SomeWindow(){SelectedDirectories=new ObservableCollection();}
public void AddDirectory(字符串路径){
添加(新目录信息(路径));
}
}
如果最终使用该FileScanner类,则需要实现INotifyCollectionChanged—这样,列表框就知道动态添加/删除哪些内容。

(请参阅下面的更新)。WPF似乎工作正常。我把你的代码放进了一个新项目每当我单击按钮调用AddDirectory时,列表框都会更新。您不需要再进行任何代码更改。 问题似乎是别的。。您的UI中有多个线程吗

我没有文件扫描程序类型。所以我创建了一个假人,如下所示

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;      }
   }
    (见下文更新)。WPF似乎工作正常。我把你的代码放进了一个新项目每当我单击按钮调用AddDirectory时,列表框都会更新。您不需要再进行任何代码更改。 问题似乎是别的。。您的UI中有多个线程吗

    我没有文件扫描程序类型。所以我创建了一个假人,如下所示

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

您的代码之所以有效,是因为列表的获取者每次都返回一个新列表-如果他返回相同的列表(即,在FileScanner的.ctor处实例化的列表,这显然不起作用)。您的代码之所以有效,是因为列表的获取者每次都返回一个新列表-如果他返回相同的列表(例如,在FileScanner的.ctor处实例化的列表,这完全不起作用)你是对的w.r.t.为什么我以前的代码段有效。更新。+1我最终做的是将集合抽象到ObservableCollection中的presenter类中,然后仅在需要时将其传递给scanner类。你是对的w.r.t.为什么我以前的代码段有效。更新。+1我最终做的是抽象集合在ObservaleCollection中将选择传递给presenter类,然后仅在需要时将其传递给scanner类。