c# - 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>
第二个窗口的代码隐藏:
public partial class UsbFileSelector : Window
{
public ObservableCollection<UsbFile> UsbFiles { get; set; } = new ObservableCollection<UsbFile>();
public UsbFileSelector()
{
InitializeComponent();
}
}
解决方案
在窗口内,您可以看到 InitializeComponent 方法。它创建在 XAML 中定义的所有内容并应用所有绑定。在使用您的空集合(您使用默认属性值创建)应用绑定后,绑定将不知道该属性的任何更改,这是正确的答案。
但是实现 INotifyPropertyChanged 更多的是关于视图模型实例,而不是视觉。
如果你想绑定,我真的建议你对窗口和控件使用依赖属性。有一些原因:
- 依赖属性设置器具有内置的通知机制。
- 如果将一个 DP 绑定到另一个 DP,则值在它们之间共享。
- 毕竟是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 中快速找到问题 =)
推荐阅读
- python - Medium.com 如何在不受 XSS 攻击的情况下允许嵌入?
- javascript - 当滚动到顶部而不是底部时,Ajax 工作
- iis - IIS 可能缓存 Active Directory 服务器的状态
- java - 用于批量插入的 Spring Async
- java - 使用无界通配符会捕获错误但仅在使用原始类型时才会被标记为警告的情况
- sql - 如何在 PIVOT SQL 中使用 0 输出转换(空)值
- r - 基于边缘属性的最短路径与 igraph
- angular - Angular-Cli 与 ng-serve
- excel - 将另一个单元格值插入 IF 函数
- c# - 如何将值添加到线程本地列表