使用 HierarchicalDataTemplate 的 WPF TreeView MVVM 像同一个词一样进行奇怪的更新
WPF TreeView MVVM using HierarchicalDataTemplate is strange updating like same word
我想显示用户的文件夹
(C:\Food\BBQ\Recipe\Recipefile.txt)
enter image description here
enter image description here
像那样
但结果是...
enter image description here
我做了一个项目 MVVM patteron wpf
使用 ViewModel.cs 和视图
使用 HierarchicalDataTemplate
这是我的代码
window1.xaml
<Window.Resources>
<ObjectDataProvider x:Key="ObjectDataProviderKey">
<ObjectDataProvider.ObjectInstance>
<vm:FolderViewModel FullPath="C:\Food"/>
</ObjectDataProvider.ObjectInstance>
</ObjectDataProvider>
<HierarchicalDataTemplate
DataType="{x:Type vm:FolderViewModel}"
ItemsSource="{Binding Path=SubFolderCollection}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
<TreeView Name="folderTreeView" Grid.ColumnSpan="2" Grid.Row="2">
<TreeViewItem
Header="Favorit"
ItemsSource="{Binding Source={StaticResource ObjectDataProviderKey}, Path=SubFolderCollection}" />
</TreeView>
和
视图模型
文件夹ViewModel.cs
namespace TEST.ViewModels.TreeView
{
public class FolderViewModel : INotifyPropertyChanging
{
namespace TEST.ViewModels.TreeView
{
public class FolderViewModel : INotifyPropertyChanging
{
#region Field
private DirectoryInfo directoryInfo;
private ObservableCollection<FolderViewModel> subFolderCollection;
private ObservableCollection<FileInfo> fileInfoCollection;
#endregion
#region - FullPath
public string FullPath
{
get
{
return directoryInfo.FullName;
}
set
{
if (Directory.Exists(value))
{
directoryInfo = new DirectoryInfo(value);
}
else
{
throw new ArgumentException("No exist.", "FullPath");
}
}
}
#endregion
#region - Name
private string _Name = string.Empty;
public event PropertyChangingEventHandler PropertyChanging;
public string Name
{
get
{
_Name = directoryInfo.Name;
return _Name;
}
set
{
_Name = value;
OnpropertyChanaged("Name");
}
}
private void OnpropertyChanaged(string v)
{
throw new NotImplementedException();
}
#endregion
#region - SubFolderCollection
public ObservableCollection<FolderViewModel> SubFolderCollection
{
get
{
if (subFolderCollection == null)
{
subFolderCollection = new ObservableCollection<FolderViewModel>();
DirectoryInfo[] directoryInfoArray = directoryInfo.GetDirectories();
//DirectoryInfo[] directoryInfoArray = (DirectoryInfo[])this.directoryInfo.GetFileSystemInfos();
for (int i = 0; i < directoryInfoArray.Length; i++)
{
FolderViewModel folder = new FolderViewModel();
FullPath = directoryInfoArray[i].FullName;
this.subFolderCollection.Add(folder);
}
}
return subFolderCollection;
}
}
#endregion
#region FileInfoCollection
public ObservableCollection<FileInfo> FileInfoCollection
{
get
{
if (this.fileInfoCollection == null)
{
this.fileInfoCollection = new ObservableCollection<FileInfo>();
FileInfo[] fileInfoArray = this.directoryInfo.GetFiles();
for (int i = 0; i < fileInfoArray.Length; i++)
{
this.fileInfoCollection.Add(fileInfoArray[i]);
}
}
return this.fileInfoCollection;
}
}
#endregion
#region - Folder()
public FolderViewModel()
{
FullPath = @"C:\Food\";
}
#endregion
}
}
我该怎么办??
如果我没理解错的话。要实现您想要的方式,您可以这样做。
MainWindow.xaml
<TreeView ItemsSource="{Binding TreeModel}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Child}">
<Grid>
<Label Content="{Binding Name}"/>
</Grid>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
然后你的 ViewModel 你可以创建一个集合,它遍历你的文件夹并添加文件夹和文件名
MainViewModel.cs
public ObservableCollection<DirModel> TreeModel { get; set; }
public MainViewModel()
{
TreeModel = new ObservableCollection<DirModel>();
Load();
}
void Load()
{
var root = "C:\TEST";
foreach (var dirInfo in new DirectoryInfo(root).GetDirectories())
{
var dir = new DirModel() { Name = dirInfo.Name };
foreach (var sb in dirInfo.GetDirectories())
{
var sDir = new ChildDirModel() { Name = sb.Name };
var sFile = new FileModel() { Name = sb.GetFiles().First().Name };
sDir.Child.Add(sFile);
dir.Child.Add(sDir);
}
TreeModel.Add(dir);
}
}
最后创建一个代表您的结构的模型class
public class DirModel
{
public string Name { get; set; }
public ObservableCollection<ChildDirModel> Child { get; set; }
public DirModel()
{
Child = new ObservableCollection<ChildDirModel>();
}
}
public class ChildDirModel
{
public string Name { get; set; }
public ObservableCollection<FileModel> Child { get; set; }
public ChildDirModel()
{
Child = new ObservableCollection<FileModel>();
}
}
public class FileModel
{
public string Name { get; set; }
}
您的应用程序将如下所示
我想显示用户的文件夹 (C:\Food\BBQ\Recipe\Recipefile.txt)
enter image description here
enter image description here
像那样 但结果是...
enter image description here
我做了一个项目 MVVM patteron wpf 使用 ViewModel.cs 和视图 使用 HierarchicalDataTemplate
这是我的代码
window1.xaml
<Window.Resources>
<ObjectDataProvider x:Key="ObjectDataProviderKey">
<ObjectDataProvider.ObjectInstance>
<vm:FolderViewModel FullPath="C:\Food"/>
</ObjectDataProvider.ObjectInstance>
</ObjectDataProvider>
<HierarchicalDataTemplate
DataType="{x:Type vm:FolderViewModel}"
ItemsSource="{Binding Path=SubFolderCollection}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
<TreeView Name="folderTreeView" Grid.ColumnSpan="2" Grid.Row="2">
<TreeViewItem
Header="Favorit"
ItemsSource="{Binding Source={StaticResource ObjectDataProviderKey}, Path=SubFolderCollection}" />
</TreeView>
和 视图模型 文件夹ViewModel.cs
namespace TEST.ViewModels.TreeView
{
public class FolderViewModel : INotifyPropertyChanging
{
namespace TEST.ViewModels.TreeView
{
public class FolderViewModel : INotifyPropertyChanging
{
#region Field
private DirectoryInfo directoryInfo;
private ObservableCollection<FolderViewModel> subFolderCollection;
private ObservableCollection<FileInfo> fileInfoCollection;
#endregion
#region - FullPath
public string FullPath
{
get
{
return directoryInfo.FullName;
}
set
{
if (Directory.Exists(value))
{
directoryInfo = new DirectoryInfo(value);
}
else
{
throw new ArgumentException("No exist.", "FullPath");
}
}
}
#endregion
#region - Name
private string _Name = string.Empty;
public event PropertyChangingEventHandler PropertyChanging;
public string Name
{
get
{
_Name = directoryInfo.Name;
return _Name;
}
set
{
_Name = value;
OnpropertyChanaged("Name");
}
}
private void OnpropertyChanaged(string v)
{
throw new NotImplementedException();
}
#endregion
#region - SubFolderCollection
public ObservableCollection<FolderViewModel> SubFolderCollection
{
get
{
if (subFolderCollection == null)
{
subFolderCollection = new ObservableCollection<FolderViewModel>();
DirectoryInfo[] directoryInfoArray = directoryInfo.GetDirectories();
//DirectoryInfo[] directoryInfoArray = (DirectoryInfo[])this.directoryInfo.GetFileSystemInfos();
for (int i = 0; i < directoryInfoArray.Length; i++)
{
FolderViewModel folder = new FolderViewModel();
FullPath = directoryInfoArray[i].FullName;
this.subFolderCollection.Add(folder);
}
}
return subFolderCollection;
}
}
#endregion
#region FileInfoCollection
public ObservableCollection<FileInfo> FileInfoCollection
{
get
{
if (this.fileInfoCollection == null)
{
this.fileInfoCollection = new ObservableCollection<FileInfo>();
FileInfo[] fileInfoArray = this.directoryInfo.GetFiles();
for (int i = 0; i < fileInfoArray.Length; i++)
{
this.fileInfoCollection.Add(fileInfoArray[i]);
}
}
return this.fileInfoCollection;
}
}
#endregion
#region - Folder()
public FolderViewModel()
{
FullPath = @"C:\Food\";
}
#endregion
}
}
我该怎么办??
如果我没理解错的话。要实现您想要的方式,您可以这样做。
MainWindow.xaml
<TreeView ItemsSource="{Binding TreeModel}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Child}">
<Grid>
<Label Content="{Binding Name}"/>
</Grid>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
然后你的 ViewModel 你可以创建一个集合,它遍历你的文件夹并添加文件夹和文件名
MainViewModel.cs
public ObservableCollection<DirModel> TreeModel { get; set; }
public MainViewModel()
{
TreeModel = new ObservableCollection<DirModel>();
Load();
}
void Load()
{
var root = "C:\TEST";
foreach (var dirInfo in new DirectoryInfo(root).GetDirectories())
{
var dir = new DirModel() { Name = dirInfo.Name };
foreach (var sb in dirInfo.GetDirectories())
{
var sDir = new ChildDirModel() { Name = sb.Name };
var sFile = new FileModel() { Name = sb.GetFiles().First().Name };
sDir.Child.Add(sFile);
dir.Child.Add(sDir);
}
TreeModel.Add(dir);
}
}
最后创建一个代表您的结构的模型class
public class DirModel
{
public string Name { get; set; }
public ObservableCollection<ChildDirModel> Child { get; set; }
public DirModel()
{
Child = new ObservableCollection<ChildDirModel>();
}
}
public class ChildDirModel
{
public string Name { get; set; }
public ObservableCollection<FileModel> Child { get; set; }
public ChildDirModel()
{
Child = new ObservableCollection<FileModel>();
}
}
public class FileModel
{
public string Name { get; set; }
}
您的应用程序将如下所示