为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
森栏 2021-05-21 17:10:28
主窗口正在侦听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>
查看完整描述

3 回答

?
开心每一天1111

TA贡献1836条经验 获得超13个赞

在窗口内,您可以看到InitializeComponent方法。它创建XAML中定义的所有内容,并应用所有绑定。在使用空收集器(已使用默认属性值创建)应用绑定之后,绑定将不知道该属性的任何更改,这是正确的答案。

但是实现INotifyPropertyChanged的目的更多是关于视图模型实例,而不是视觉对象。

我真的建议您如果要绑定,请对窗口和控件使用依赖项属性。这有一些原因:

  1. 依赖项属性设置器具有内置的通知机制。

  2. 如果将一个DP绑定到另一DP,则它们之间将共享值。

  3. 毕竟是WPF方法=)

这是更改后您的窗口的外观

 public partial class UsbFileSelector : Window

    {

        public static readonly DependencyProperty UsbFilesProperty = 

            DependencyProperty.Register("UsbFiles", typeof(ObservableCollection<UsbFile>), typeof(UsbFileSelector));


        public ObservableCollection<UsbFile> UsbFiles 

        {

            get { return (ObservableCollection<UsbFile>) GetValue(UsbFilesProperty); }

            set { SetValue(UsbFilesProperty, value); }

        }


        public UsbFileSelector()

        {

            InitializeComponent();

        }

    }

另外,我强烈建议您在开发WPF时使用某些WPF检查器工具,例如snoop。您可以在应用程序运行时浏览控件和属性,并可以从代码或stackoverflow =)中快速找到问题


查看完整回答
反对 回复 2021-05-23
?
忽然笑

TA贡献1806条经验 获得超5个赞


var usbFileSelector = new UsbFileSelector()

{

   Owner = this,

   UsbFiles = NewUsbFiles

};

您正在为该UsbFiles属性分配新值,而不触发该属性的属性更改通知。


您可以实现INotifyPropertyChanged并触发PropertyChanged事件,也可以使UsbFiles成为依赖项属性。


或者您NewUsbFiles在调用InitializeComponent之前将其作为构造函数参数传递并分配给它


public UsbFileSelector(ObservableCollection<UsbFile> usbFiles)

{

    UsbFiles = usbFiles;

    InitializeComponent();

}

并这样称呼它:


var usbFileSelector = new UsbFileSelector(NewUsbFiles)

{

   Owner = this

};

请注意,如果您始终传递新的集合,则实际上不需要使用ObservableCollection。您永远不会在集合中添加元素或从集合中删除元素,因此不需要更改通知。


查看完整回答
反对 回复 2021-05-23
  • 3 回答
  • 0 关注
  • 119 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信