我遇到了处理类的困难。我知道我必须制作自己的自定义类'treenode',它将具有类似于winforms treenode的属性“parent”。
然而,在wpf中,我需要两种不同类型的treenodes,以便可以通过数据类型正确地绑定wpf。我在wpf中使用家族的工作示例,只是不确定如何将我的winform版本翻译成wpf。有人能帮我让我的winform版本在wpf上运行吗?
最终目标是使用与winforms示例中相同的目录和文件填充WPF中的树形视图。但是,WPF版本的样式应保持显示文件和文件夹的“图标”。
我希望有人能帮助我使其正常工作。欢迎任何建议和评论。
ViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using System.Windows.Input;
using System.Linq;
namespace WpfApplication1
{
public class ViewModel : ObservableObject
{
// Properties
private ObservableCollection<DirectoryNode> directoryNodes;
public ObservableCollection<DirectoryNode> DirectoryNodes
{
get { return directoryNodes; }
set
{
directoryNodes = value;
NotifyPropertyChanged("DirectoryNodes");
}
}
private ObservableCollection<string> formats;
public ObservableCollection<string> Formats
{
get { return formats; }
set
{
formats = value;
NotifyPropertyChanged("Formats");
}
}
private ObservableCollection<string> directories;
public ObservableCollection<string> Directories
{
get { return directories; }
set
{
directories = value;
NotifyPropertyChanged("Directories");
}
}
// Creating data for testings
public ViewModel()
{
Formats = new ObservableCollection<string>();
Directories = new ObservableCollection<string>();
DirectoryNodes = new ObservableCollection<DirectoryNode>();
// create some dummy test data, eventually will be push to GUI
Formats.Add(".txt");
Formats.Add(".png");
Directories.Add(System.Environment.GetEnvironmentVariable("USERPROFILE"));
PopulateTree(Directories);
}
// Functions
static bool IsValidFileFormat(string filename, ObservableCollection<string> formats)
{
if (formats.Count == 0) return true;
string ext = Path.GetExtension(filename);
bool results = formats.Any(fileType => fileType.Equals(ext, StringComparison.OrdinalIgnoreCase));
return results;
}
public static DirectoryNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
DirectoryNode directoryNode = new DirectoryNode(){Filename=directoryInfo.Name};
foreach (var directory in directoryInfo.GetDirectories())
{
try
{
directoryNode.Children.Add(CreateDirectoryNode(directory));
}
catch (UnauthorizedAccessException) { }
}
foreach (var file in directoryInfo.GetFiles())
{
if (IsValidFileFormat(file.FullName, Formats))
{
FileNode node = new FileNode() { Filename = file.FullName };
directoryNode.Children.Add(node);
}
}
return directoryNode;
}
public void PopulateTree(ObservableCollection<string> directories)
{
foreach (string directoryPath in directories)
{
if (Directory.Exists(directoryPath))
{
DirectoryInfo directoryInfo = new DirectoryInfo(directoryPath);
DirectoryNodes.Add(CreateDirectoryNode(directoryInfo));
}
}
}
}
public class FileNode
{
public string Filepath { get; set; }
public string Filename { get; set; }
public DirectoryNode Parent { get; set; }
}
public class DirectoryNode
{
public string Filepath { get; set; }
public string Filename { get; set; }
public DirectoryNode Parent { get; set; }
public ObservableCollection<FileNode> Children { get; set; }
}
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
MainWindow.Xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:self="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="300"
WindowStartupLocation="CenterScreen">
<Window.DataContext>
<self:ViewModel/>
</Window.DataContext>
<Grid Margin="5">
<TreeView ItemsSource="{Binding Directories}" Grid.Row="1" Grid.ColumnSpan="2">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type self:DirectoryNode}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Label VerticalAlignment="Center" FontFamily="WingDings" Content="1"/>
<TextBlock Text="{Binding Filename}" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type self:FileNode}">
<StackPanel Orientation="Horizontal">
<Label VerticalAlignment="Center" FontFamily="WingDings" Content="2"/>
<TextBlock Text="{Binding Filename}" />
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Window>
工作中的Winforms示例
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Linq;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public static List<string> formats = new List<string>();
public Form1()
{
InitializeComponent();
//add userfolder
List<string> Directories = new List<string>();
Directories.Add(System.Environment.GetEnvironmentVariable("USERPROFILE"));
// get formats accepted
formats.Add(".txt");
formats.Add(".png");
PopulateTree(Directories, formats);
}
static bool IsValidFileFormat(string filename, List<string> formats)
{
if (formats.Count == 0) return true;
string ext = Path.GetExtension(filename);
bool results = formats.Any(fileType => fileType.Equals(ext, StringComparison.OrdinalIgnoreCase));
return results;
}
public static TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
TreeNode directoryNode = new TreeNode(directoryInfo.Name);
foreach (var directory in directoryInfo.GetDirectories())
{
try
{
directoryNode.Nodes.Add(CreateDirectoryNode(directory));
}
catch (UnauthorizedAccessException) { }
}
foreach (var file in directoryInfo.GetFiles())
{
if (IsValidFileFormat(file.FullName, formats))
{
TreeNode node = new TreeNode(file.FullName);
node.ForeColor = Color.Red;
directoryNode.Nodes.Add(node);
}
}
return directoryNode;
}
public void PopulateTree(List<string> directories, List<string> formats)
{
// main collection of nodes which are used to populate treeview
List<TreeNode> treeNodes = new List<TreeNode>();
foreach (string directoryPath in directories)
{
if (Directory.Exists(directoryPath))
{
DirectoryInfo directoryInfo = new DirectoryInfo(directoryPath);
treeNodes.Add(CreateDirectoryNode(directoryInfo));
}
}
treeView1.Nodes.AddRange(treeNodes.ToArray());
}
}
}