除非点击,否则C#WPF Gridview不会显示数据

时间:2017-11-15 13:46:19

标签: c# wpf datagrid

我正在学习WPF / C#并尝试开发一个小应用程序,列出数据网格中的文件名(Windows 10,.Net frame 4.5) 到目前为止,代码在下面

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using System.IO;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for ProcessFiles.xaml
    /// </summary>
    public partial class ProcessFiles : Window
    {
        List<FileInfo> myFileList = new List<FileInfo>();


        public ProcessFiles()
        {
            InitializeComponent();
            dGrid.AutoGenerateColumns = true;
            dGrid.UpdateLayout();
        }

        private void pButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Task.Factory.StartNew(() => ListMyFiles(myFileList));
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error " +ex.Message);
            }
            finally
            {
                MessageBox.Show("Done.");
            }

            dGrid.ItemsSource = myFileList;
        }

        private void ListMyFiles(List<FileInfo> mylist)
        {
            //throw new NotImplementedException();

            foreach (FileInfo f in new DirectoryInfo(@"D:\Dummy2").GetFiles("*.*", SearchOption.TopDirectoryOnly))
            {
                // var currentFile = f;
                System.Threading.Thread.Sleep(10);
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    this.ReadyItem.Content = "Updating..." + f.FullName;
                    mylist.Add(f);
                }), DispatcherPriority.Background);
            }

        }
    }
}

我在Dispatcher任务完成后自动刷新数据网格面临两难选择。如果我没有在按钮点击事件中的某个地方使用MessageBox.Show()激活GUI线程,则GridView不会显示任何数据,但是,最大化主窗口,添加MessageBox show等开始显示列已填满。

我必须缺少什么?

2 个答案:

答案 0 :(得分:2)

只需将List<T>更改为ObservableCollection<T>即可通知ItemsSource有关更改的信息。 WPF控件通常会收听INotifyPropertyChangedINotifyCollectionChanged个事件:

ObservableCollection<FileInfo> myFileList = new ObservableCollection<FileInfo>();

答案 1 :(得分:1)

 public partial class ProcessFiles : Window, INotifyPropertyChanged
{

    public void SetPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private ObservableCollection<FileInfo> myFileList = new ObservableCollection<FileInfo>();

    public ObservableCollection<FileInfo> MyFileList
    {
         get{return myFileList;}
         set
            {
               myFileList = value;
               SetPropertyChanged("MyFileList");
            }
    }

    public ProcessFiles()
    {
        InitializeComponent();
        dGrid.AutoGenerateColumns = true;
        dGrid.UpdateLayout();
    }

    private void pButton_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            Task.Factory.StartNew(() => ListMyFiles(myFileList));
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error " +ex.Message);
        }
        finally
        {
            MessageBox.Show("Done.");
        }

        dGrid.ItemsSource = MyFileList;
    }

    private void ListMyFiles(ObservableCollection<FileInfo> mylist)
    {
        //throw new NotImplementedException();

        foreach (FileInfo f in new DirectoryInfo(@"D:\Dummy2").GetFiles("*.*", SearchOption.TopDirectoryOnly))
        {
            // var currentFile = f;
            System.Threading.Thread.Sleep(10);
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.ReadyItem.Content = "Updating..." + f.FullName;
                mylist.Add(f);
            }), DispatcherPriority.Background);
        }

    }

这应该有效