C# 如何在WPF中将集合绑定到ListView

C# 如何在WPF中将集合绑定到ListView,c#,.net,wpf,listview,data-binding,C#,.net,Wpf,Listview,Data Binding,我有一个程序,可以在目录中搜索符合特定条件的文件。这个搜索过程花费了很长的时间,所以我必须异步调用它。当搜索算法找到一个文件时,它会触发一个事件。MyMainWindow实例侦听此事件,需要更新GUI。如何将这些“添加的”文件绑定到列表视图?我想我可以使用一个ObservableCollection实例,但我不知道如何绑定它 我已经去掉了所有不相关的控件和代码。这是两个相关的文件 MainWindow.xaml: <Window x:Class="Example.MainWindow"

我有一个程序,可以在目录中搜索符合特定条件的文件。这个搜索过程花费了很长的时间,所以我必须异步调用它。当搜索算法找到一个文件时,它会触发一个事件。My
MainWindow
实例侦听此事件,需要更新GUI。如何将这些“添加的”文件绑定到
列表视图
?我想我可以使用一个
ObservableCollection
实例,但我不知道如何绑定它

我已经去掉了所有不相关的控件和代码。这是两个相关的文件

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>

下面是一个简单的例子

您的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>

名称
被改进的
您的代码隐藏

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);
                }
            });
    }
}
公共部分类主窗口:窗口
{
公共类文件信息
{
公共字符串名称{get;set;}
公共日期时间LastModified{get;set;}
公共文件信息(字符串名称)
{
名称=名称;
LastModified=DateTime.Now;
}
}
ObservableCollection mFileNames=新的ObservableCollection();
公共可观测集合文件名
{
得到
{
返回文件名;
}
}
公共主窗口()
{
DataContext=this;
初始化组件();
}
已加载私有无效窗口(对象发送器、路由目标)
{
ThreadPool.QueueUserWorkItem((x)=>
{
while(true)
{
Dispatcher.BeginInvoke((操作)(()=>
{
添加(新文件信息(“X”));
}));
睡眠(500);
}
});
}
}

如果运行此问题,您将注意到列表框每半秒更新一个新项目。基本上,需要注意的关键是,ObservableCollection只能从UI线程更新,因此,如果您重构上述代码,您需要以某种方式使用当前UI线程的Dispatcher来更新它

我已经解决了线程情况。在
可观测集合中使用对象如何?例如
FileInfo
对象的集合。如何将文件名及其目录绑定到
列表视图中的列?我刚刚更新了答案。如果您的
FileInfo
是可变的,并且在将其添加到列表后更改了其属性,则必须在其上实现
INotifyPropertyChanged
,以便UI更新我正在使用。话虽如此,您是否有任何理由使用
列表框而不是
列表视图
。。。基本上,您可以在XAML中绑定任何公共属性。FileInfo应该很好用,我必须添加一个DataContext。
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);
                }
            });
    }
}