C#除非单击,否则WPF Gridview不会显示数据
我正在学习WPF/C,并试图开发一个在数据网格中列出文件名的小应用程序(Windows 10、.Net frame 4.5) 到目前为止,代码如下C#除非单击,否则WPF Gridview不会显示数据,c#,wpf,datagrid,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 S
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);
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Threading;
使用System.IO;
命名空间WpfApplication1
{
///
///ProcessFiles.xaml的交互逻辑
///
公共部分类ProcessFiles:窗口
{
List myFileList=新列表();
公共进程文件()
{
初始化组件();
dGrid.AutoGenerateColumns=true;
dGrid.UpdateLayout();
}
私有无效按钮单击(对象发送方,路由目标)
{
尝试
{
Task.Factory.StartNew(()=>ListMyFiles(myFileList));
}
捕获(例外情况除外)
{
MessageBox.Show(“错误”+ex.Message);
}
最后
{
MessageBox.Show(“完成”);
}
dGrid.ItemsSource=myFileList;
}
私有无效列表MyFiles(列表mylist)
{
//抛出新的NotImplementedException();
foreach(新目录信息(@“D:\Dummy2”).GetFiles(“**”,SearchOption.TopDirectoryOnly)中的文件信息f)
{
//var currentFile=f;
系统线程线程睡眠(10);
Dispatcher.BeginInvoke(新操作(()=>
{
this.ReadyItem.Content=“更新…”+f.FullName;
添加(f);
}),DispatcherPriority.Background);
}
}
}
}
在Dispatcher任务完成后自动刷新datagrid一次,我面临着一个两难境地。如果我没有在button clicked事件中的某个地方使用MessageBox.Show()激活GUI线程,GridView不会显示任何数据,但是,最大化主窗口,添加MessageBox Show等会开始显示填充的列
我必须缺少什么?只需将
列表更改为可观察集合
,以通知项目资源
有关更改的信息。WPF控件通常侦听INotifyPropertyChanged
或INotifyCollectionChanged
事件:
ObservableCollection myFileList=新的ObservableCollection()代码>公共部分类进程文件:窗口,INotifyPropertyChanged
{
public void SetPropertyChanged(字符串propertyName)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
公共事件属性更改事件处理程序属性更改;
私有ObservableCollection myFileList=新ObservableCollection();
公共可观察收集MyFileList
{
获取{return myFileList;}
设置
{
myFileList=值;
SetPropertyChanged(“MyFileList”);
}
}
公共进程文件()
{
初始化组件();
dGrid.AutoGenerateColumns=true;
dGrid.UpdateLayout();
}
私有无效按钮单击(对象发送方,路由目标)
{
尝试
{
Task.Factory.StartNew(()=>ListMyFiles(myFileList));
}
捕获(例外情况除外)
{
MessageBox.Show(“错误”+ex.Message);
}
最后
{
MessageBox.Show(“完成”);
}
dGrid.ItemsSource=MyFileList;
}
私有void ListMyFiles(ObservableCollection mylist)
{
//抛出新的NotImplementedException();
foreach(新目录信息(@“D:\Dummy2”).GetFiles(“**”,SearchOption.TopDirectoryOnly)中的文件信息f)
{
//var currentFile=f;
系统线程线程睡眠(10);
Dispatcher.BeginInvoke(新操作(()=>
{
this.ReadyItem.Content=“更新…”+f.FullName;
添加(f);
}),DispatcherPriority.Background);
}
}
这应该行得通您是否在实现INotifyPropertyChanged以让UI知道您的gridview的ItemSource已更改?正如我所提到的,我是C#和WPF的真正初学者,我在这里检查了许多解释INotifyPropertyChanged的线程,这超出了我的理解。我在这一点上遇到了一个错误“PropertyChanged?”调用(这个,新的PropertyChangedEventArgs(propertyName));"哪个错误?这是通知UI的事件的实现changes@RajeshThampi我对我的答案做了一个修正。我在ListMyFrm方法上犯了一个错误。但是现在尝试一下,恐怕你不能简单地用这种方式更新你的UI。也许你应该考虑使用一个后台工作人员来改变进度。获取图像()所示的错误。我有另一个后台工作程序示例,试图了解Dispatcher invoke和后台工作程序之间的主要区别。谢谢
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);
}
}