猿问

WPF列表框未填充ObservableCollection中的项目

主窗口正在侦听USB设备的插入/拔出。如果是USB密钥/磁盘,它将从该设备收集文件列表,并在第二个窗口中显示该列表。


在调试时,我可以看到NewUsbFiles observablecollection包含117个项目。我看到属性UsbFile(在调用showdialog之前)有117个项目,但是列表框为空。


有什么想法吗 ?


填充/创建第二个窗口的方法:


NewUsbFiles = new ObservableCollection<UsbFile>();

UpdateNewUsbFiles(driveName);


Application.Current.Dispatcher.Invoke(delegate

{

   var usbFileSelector = new UsbFileSelector()

   {

       Owner = this,

       UsbFiles = NewUsbFiles

    };

    usbFileSelector.ShowDialog();

});

UsbFile类:


 public class UsbFile 

    {

        public string UsbFileName { get; set; }

        public string OnTableFileName { get; set; }

        public bool Ignored { get; set; } = false;


        public UsbFile(string fileName)

        {

            var fileInfo = new FileInfo(fileName);

            UsbFileName = fileInfo.FullName;

            OnTableFileName = $"{fileInfo.CreationTime:yyMMddHHmmsss}_{fileInfo.Name}";

        }

    }

第二个窗口的XAML:


<Window

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:MainWindow="clr-namespace:PartyPictures.WPF.MainWindow" x:Name="wUsbFileSelector"

    x:Class="PartyPictures.WPF.UsbFileSelector"

        mc:Ignorable="d"

        Title="USB" HorizontalAlignment="Center" VerticalAlignment="Center" WindowStyle="ToolWindow" ScrollViewer.VerticalScrollBarVisibility="Auto" SizeToContent="WidthAndHeight">

    <StackPanel x:Name="spUsbFileList">

        <ListBox  x:Name="ImageListbox"

                  DataContext="{Binding ElementName=wUsbFileSelector}"

                 ItemsSource="{Binding UsbFiles}" 

                 Background="AliceBlue" ScrollViewer.HorizontalScrollBarVisibility="Disabled" MinWidth="200" MinHeight="200">

        </ListBox>

    </StackPanel>

</Window>



森栏
浏览 120回答 3
3回答

开心每一天1111

在窗口内,您可以看到InitializeComponent方法。它创建XAML中定义的所有内容,并应用所有绑定。在使用空收集器(已使用默认属性值创建)应用绑定之后,绑定将不知道该属性的任何更改,这是正确的答案。但是实现INotifyPropertyChanged的目的更多是关于视图模型实例,而不是视觉对象。我真的建议您如果要绑定,请对窗口和控件使用依赖项属性。这有一些原因:依赖项属性设置器具有内置的通知机制。如果将一个DP绑定到另一DP,则它们之间将共享值。毕竟是WPF方法=)这是更改后您的窗口的外观&nbsp;public partial class UsbFileSelector : Window&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public static readonly DependencyProperty UsbFilesProperty =&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DependencyProperty.Register("UsbFiles", typeof(ObservableCollection<UsbFile>), typeof(UsbFileSelector));&nbsp; &nbsp; &nbsp; &nbsp; public ObservableCollection<UsbFile> UsbFiles&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get { return (ObservableCollection<UsbFile>) GetValue(UsbFilesProperty); }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set { SetValue(UsbFilesProperty, value); }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public UsbFileSelector()&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; InitializeComponent();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }另外,我强烈建议您在开发WPF时使用某些WPF检查器工具,例如snoop。您可以在应用程序运行时浏览控件和属性,并可以从代码或stackoverflow =)中快速找到问题

忽然笑

在var usbFileSelector = new UsbFileSelector(){&nbsp; &nbsp;Owner = this,&nbsp; &nbsp;UsbFiles = NewUsbFiles};您正在为该UsbFiles属性分配新值,而不触发该属性的属性更改通知。您可以实现INotifyPropertyChanged并触发PropertyChanged事件,也可以使UsbFiles成为依赖项属性。或者您NewUsbFiles在调用InitializeComponent之前将其作为构造函数参数传递并分配给它public UsbFileSelector(ObservableCollection<UsbFile> usbFiles){&nbsp; &nbsp; UsbFiles = usbFiles;&nbsp; &nbsp; InitializeComponent();}并这样称呼它:var usbFileSelector = new UsbFileSelector(NewUsbFiles){&nbsp; &nbsp;Owner = this};请注意,如果您始终传递新的集合,则实际上不需要使用ObservableCollection。您永远不会在集合中添加元素或从集合中删除元素,因此不需要更改通知。
随时随地看视频慕课网APP
我要回答