【问题标题】:C# WPF Gridview will not show data Unless clickedC# WPF Gridview 不会显示数据除非单击
【发布时间】:2017-11-15 23:15:23
【问题描述】:

我正在学习 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 显示等开始显示填充的列。

我一定错过了什么?

【问题讨论】:

  • 您是否正在实施 INotifyPropertyChanged 以让 UI 知道您的 gridview 的 ItemSource 已更改?
  • 正如我所提到的,我是一个真正的 C# 和 WPF 初学者,我在这里查看了许多解释 INotifyPropertyChanged 的​​线程,这超出了我的理解范围。

标签: c# wpf datagrid


【解决方案1】:

只需将List&lt;T&gt; 更改为ObservableCollection&lt;T&gt; 即可通知ItemsSource 有关更改。 WPF 控件一般会监听INotifyPropertyChangedINotifyCollectionChanged 事件:

ObservableCollection&lt;FileInfo&gt; myFileList = new ObservableCollection&lt;FileInfo&gt;();.

【讨论】:

    【解决方案2】:
     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);
            }
    
        }
    

    这应该可以工作

    【讨论】:

    • 我在此语句“PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));”中遇到错误
    • 哪个错误?这是通知 UI 更改的事件的实现
    • @RajeshThampi 我在我的回答中做了一个修复。我在 ListMyFiles 方法上犯了一个错误。立即尝试
    • 但是我担心你不能简单地以这种方式更新你的用户界面。也许您应该考虑使用带有 Progress Changed 事件的后台工作人员的可能性
    • 我收到了图片中的错误 (ibb.co/jANvQ6)。我有另一个后台工作人员的例子,并试图了解 Dispatcher 调用和后台工作人员之间的主要区别。谢谢
    猜你喜欢
    • 1970-01-01
    • 2017-03-11
    • 2021-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    • 2016-10-16
    • 2014-02-21
    • 1970-01-01
    相关资源
    最近更新 更多