简体   繁体   English

如何将集合绑定到WPF中的ListView

[英]How to bind a collection to a ListView in WPF

I have a program that searches a directory for files matching certain criteria. 我有一个程序在目录中搜索符合特定条件的文件。 This search process takes a long time, 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. 我的MainWindow实例侦听此事件,需要更新GUI。 How can I bind these "added" files to a ListView ? 如何将这些“添加”文件绑定到ListView I figured that I could use an ObservableCollection<FileInfo> instance, but I can't figure out how to bind it. 我想我可以使用ObservableCollection<FileInfo>实例,但我无法弄清楚如何绑定它。

I've stripped out all of the irrelevant controls and code. 我已经删除了所有不相关的控件和代码。 Here are the two relevant files. 这是两个相关文件。

MainWindow.xaml: MainWindow.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: MainWindow.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
    }
}

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来更新它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM