如何将集合绑定到WPF中的ListView [英] How to bind a collection to a ListView in WPF

查看:196
本文介绍了如何将集合绑定到WPF中的ListView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序可以在目录中搜索符合特定条件的文件。这个搜索过程需要一个 long 时间,所以我必须异步调用它。当搜索算法找到一个文件时,它触发一个事件。我的 MainWindow 实例监听此事件,需要更新GUI。如何将这些添加文件绑定到一个 ListView ?我想我可以使用 ObservableCollection< FileInfo> 实例,但是我无法弄清楚如何绑定它。



我删除了所有不相关的控件和代码。以下是两个相关文件。



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 SearchHeight =395Width =525>
< Grid>
< ListView x:Name =Results>
< ListView.View>
< GridView>
< GridViewColumn Header =Filename/>
< GridViewColumn Header =Directory/>
< / GridView>
< /ListView.View>
< / ListView>
< / Grid>
< / Window>

MainWindow.xaml.cs:

 使用System.IO; 
使用System.Threading.Tasks;

public partial class MainWindow
{
private SearchLogic _backgroundSearch;

private async void Search(object sender,RoutedEventArgs e)
{
// TODO:clear结果

_backgroundSearch = new SearchLogic(,新的DirectoryInfo(C:\));
_backgroundSearch.FileAdded + = FileAdded;

await Task.Run(new Action(_backgroundSearch.Search));
}

private void FileAdded(object sender,FileAddedEventArgs eventArgs)
{
// TODO:将eventArgs.File添加到结果
// eventArgs。文件是FileInfo的一个实例
}
}


解决方案

这是一个简单的例子



您的XAML

 < Window x:Class =WpfApplication10.MainWindow
xmlns =http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns :x =http://schemas.microsoft.com/winfx/2006/xaml
标题=MainWindow
宽度=525
高度=350
加载=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;组; }
public DateTime LastModified {get;组;
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);
}
});
}
}

如果您运行此问题,您会注意到列表框每半秒更新一次新项目。基本上要注意的是ObservableCollection只能从UI线程更新,所以如果你重构上面的代码,你需要使用当前UI线程的Dispatcher来更新它


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. 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.

I've stripped out all of the irrelevant controls and code. Here are the two relevant files.

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:

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

<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

这篇关于如何将集合绑定到WPF中的ListView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆