C# 如何在 WPF 中将集合绑定到 ListView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15747780/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to bind a collection to a ListView in WPF
提问by Tyler Crompton
I have a program that searches a directory for files matching certain criteria. This search process takes a longtime, so I have to call it asynchronously. When the search algorithm finds a file, it triggers an event. My MainWindow
instance listens for this event and needs to update the GUI. How can I bind these "added" files to a ListView
? I figured that I could use an ObservableCollection<FileInfo>
instance, but I can't figure out how to bind it.
我有一个程序可以在目录中搜索符合特定条件的文件。这个搜索过程需要很长时间,所以我不得不异步调用它。当搜索算法找到一个文件时,它会触发一个事件。我的MainWindow
实例侦听此事件并需要更新 GUI。如何将这些“添加”文件绑定到ListView
? 我想我可以使用一个ObservableCollection<FileInfo>
实例,但我不知道如何绑定它。
I've stripped out all of the irrelevant controls and code. Here are the two relevant files.
我已经去掉了所有不相关的控件和代码。这是两个相关文件。
MainWindow.xaml:
主窗口.xaml:
<Window x:Class="Example.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CR Search" Height="395" Width="525">
<Grid>
<ListView x:Name="Results">
<ListView.View>
<GridView>
<GridViewColumn Header="Filename"/>
<GridViewColumn Header="Directory"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
MainWindow.xaml.cs:
主窗口.xaml.cs:
using System.IO;
using System.Threading.Tasks;
public partial class MainWindow
{
private SearchLogic _backgroundSearch;
private async void Search(object sender, RoutedEventArgs e)
{
// TODO: clear Results
_backgroundSearch = new SearchLogic("", new DirectoryInfo("C:\"));
_backgroundSearch.FileAdded += FileAdded;
await Task.Run(new Action(_backgroundSearch.Search));
}
private void FileAdded(object sender, FileAddedEventArgs eventArgs)
{
// TODO: add eventArgs.File to Results
// eventArgs.File is an instance of FileInfo
}
}
采纳答案by parapura rajkumar
Here is a simple example
这是一个简单的例子
Your XAML
你的 XAML
<Window x:Class="WpfApplication10.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525"
Height="350"
Loaded="Window_Loaded">
<Grid>
<ListBox ItemsSource="{Binding FileNames}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<Label>Name</Label>
<TextBlock Text="{Binding Name}"/>
<Label>Modified</Label>
<TextBlock Text="{Binding LastModified}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
Your Code Behind
你背后的代码
public partial class MainWindow : Window
{
public class FileInfo
{
public string Name { get; set; }
public DateTime LastModified { get; set; }
public FileInfo(string name)
{
Name = name;
LastModified = DateTime.Now;
}
}
ObservableCollection<FileInfo> mFileNames = new ObservableCollection<FileInfo>();
public ObservableCollection<FileInfo> FileNames
{
get
{
return mFileNames;
}
}
public MainWindow()
{
DataContext = this;
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem((x) =>
{
while (true)
{
Dispatcher.BeginInvoke((Action)(() =>
{
mFileNames.Add(new FileInfo("X"));
}));
Thread.Sleep(500);
}
});
}
}
If you run this problem you will notice that the listbox updates every half a second with a new item. Basically the key thing to note is that the ObservableCollection can only be updated from the UI thread so if you refactor the above code you need need to somehow use the Dispatcher of the current UI thread to update it
如果您运行此问题,您会注意到列表框每半秒更新一次新项目。基本上要注意的关键是 ObservableCollection 只能从 UI 线程更新,所以如果你重构上面的代码,你需要以某种方式使用当前 UI 线程的 Dispatcher 来更新它