我使用 MVVM 模型和代码开发了一个简单的 wpf 应用程序,如下所示。我调试代码并发现集合正在更新,但 UI 没有更新,即使我在列表框中没有看到任何记录。
编辑
<Window x:Class="Model.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF Dispatcher Demo" Height="350" Width="525">
<DockPanel>
<Grid DockPanel.Dock="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" Name="col0" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Name="textBlock1" Text="{Binding ShowPath}"
VerticalAlignment="Center" HorizontalAlignment="Left"
Margin="30" Grid.Column="0" />
<Button Name="FindButton" Content="Select Path"
Width="100" Margin="20" Click="FindButton_Click" Grid.Column="1" />
</Grid>
<ListBox Name="listBox1" ItemsSource="{Binding Path=Files}"/>
</DockPanel>
</Window>
模型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Threading;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace Model
{
public class DirectorySearchModel : INotifyPropertyChanged
{
private ObservableCollection<string> _files = new ObservableCollection<string>();
private string _showPath;
public DirectorySearchModel() { }
void ShowCurrentPath(string path)
{
ShowPath = path;
}
void AddFileToCollection(string file)
{
_files.Add(file);
}
public void Search(string path, string pattern)
{
if (System.Windows.Application.Current.Dispatcher.CheckAccess())
ShowPath = path;
else
System.Windows.Application.Current.Dispatcher.Invoke(
new Action<string>(ShowCurrentPath), DispatcherPriority.Background, new string[] { path }
);
string[] files = Directory.GetFiles(path, pattern);
foreach (string file in files)
{
if (System.Windows.Application.Current.Dispatcher.CheckAccess())
Files.Add(file);
else
System.Windows.Application.Current.Dispatcher.Invoke(new Action<string>(AddFileToCollection), DispatcherPriority.Background,
new string[] { file }
);
}
string[] dirs = System.IO.Directory.GetDirectories(path);
foreach (string dir in dirs)
Search(dir, pattern);
}
public string ShowPath
{
get
{
return _showPath;
}
set
{
_showPath = value;
OnPropertyChanged("ShowPath");
}
}
public ObservableCollection<string> Files
{
get
{
return _files;
}
set
{
_files = value;
OnPropertyChanged("Files");
}
}
public void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
主窗口.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Forms;
using System.IO;
namespace Model
{
public partial class MainWindow : Window
{
IAsyncResult cbResult;
public MainWindow()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = new DirectorySearchModel().Files;
}
private void FindButton_Click(object sender, RoutedEventArgs e)
{
FolderBrowserDialog dlg = new FolderBrowserDialog();
string path = AppDomain.CurrentDomain.BaseDirectory;
dlg.SelectedPath = path;
DialogResult result = dlg.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
path = dlg.SelectedPath;
string pattern = "*.*";
new Model.DirectorySearchModel().Search(path, pattern);
Action<string, string> proc = new Model.DirectorySearchModel().Search;
cbResult = proc.BeginInvoke(path, pattern, null, null);
}
}
}
}