【问题标题】:How to bind a collection to a ListView in WPF如何将集合绑定到 WPF 中的 ListView
【发布时间】:2013-03-22 18:48:06
【问题描述】:

我有一个程序可以在目录中搜索符合特定条件的文件。这个搜索过程需要 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 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
    }
}

【问题讨论】:

    标签: c# .net wpf listview data-binding


    【解决方案1】:

    这是一个简单的例子

    你的 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);
                    }
                });
        }
    }
    

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

    【讨论】:

    • 我已经弄清楚了线程情况。在ObservableCollection 中使用对象怎么样?例如FileInfo 对象的集合。如何将文件名及其目录绑定到ListView 中的列?
    • 我刚刚更新了我的答案。如果您的 FileInfo 是可变的,并且您在将其添加到列表后更改其属性,则您必须在其上实现 INotifyPropertyChanged 以便 UI 更新
    • 我正在使用System.IO.FileInfo class。话虽如此,您是否有任何理由使用ListBox 而不是ListView
    • 不是真的...基本上你可以在 XAML 中绑定任何公共属性。 FileInfo 应该可以正常工作
    • 我必须添加一个 DataContext。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    相关资源
    最近更新 更多