基于树视图并选择多个文件,实现文件浏览器

Ofi*_*fir 1 wpf treeview explorer file

我是WPF初学者。我在工作时开发了一个新项目,因此需要插入具有多个选择的文件资源管理器控件。

这个概念需要类似于acronis文件浏览器:(带有复选框的Treeview)

参见示例

看左边的容器,我需要实现类似的东西,我在Google上搜索了很多东西,但看到了很多实现,但是没有什么比这更好。

因为我没有很多WPF经验,所以我很难开始。

您有一些技巧或类似的项目可能对我有帮助吗?

我的项目基于MVVM DP。

谢谢

AlS*_*Ski 5

重塑Treeview非常容易,首先要绑定到您的集合,即

<Grid>
  <TreeView ItemsSource="{Binding Folders}"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

但是,然后您需要定义如何显示绑定到的数据。我假设您的项目只是FolderViewModels和FileViewModels(都具有Name属性)的IEnumerable(任何列表或数组),所以现在我们需要说明如何显示它们。您可以通过定义一个DataTemplate来做到这一点,并且由于这是一棵树,因此我们使用HeirarchicalDataTemplate,因为它也定义了subItems

<Grid.Resources>
  <HierarchicalDataTemplate DataType="{x:Type viewModel:FolderViewModel}"
                              ItemsSource="{Binding SubFoldersAndFiles}">
        <CheckBox Content="{Binding Name}"/>
  </HierarchicalDataTemplate>
<Grid.Resources/>
Run Code Online (Sandbox Code Playgroud)

文件相同,但不需要子项

<HierarchicalDataTemplate DataType="{x:Type viewModel:FolderViewModel}">
   <CheckBox Content="{Binding Name}"/>
</HierarchicalDataTemplate>
Run Code Online (Sandbox Code Playgroud)

所以把它们放在一起

<Grid>
    <Grid.Resources>
        <HierarchicalDataTemplate DataType="{x:Type viewModel:FolderViewModel}"
                              ItemsSource="{Binding SubFoldersAndFiles}">
            <CheckBox Content="{Binding Name}"/>
       </HierarchicalDataTemplate>
       <HierarchicalDataTemplate DataType="{x:Type viewModel:FolderViewModel}">
            <CheckBox Content="{Binding Name}"/>
      </HierarchicalDataTemplate>
    <Grid.Resources/>
    <TreeView ItemsSource="{Binding Folders}"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

图标 如果要显示图标,则可以更改CheckBox中的内容,我假设您将在ViewModel上定义一个Image。

        <CheckBox>
            <CheckBox.Content>
                <StackPanel Orientation="Horizontal">
                    <Image Source="{Binding Image}"/>
                    <TextBlock Text="{Binding Name}"/>
                </StackPanel>
            </CheckBox.Content>
Run Code Online (Sandbox Code Playgroud)

选拔

最后,您必须处理项目的选择。我建议将IsSelected属性添加到FileViewModel和FolderViewModels中。对于文件,这是非常简单的,只是个麻烦。

 public class FileViewModel : INotifyProperty
   ...
   public bool IsSelected //Something here to handle get/set and NotifyPropertyChanged that depends on your MVVM framework, I use ReactiveUI a lot so that's this syntax
   { 
      get { return _IsSelected;}
      set { this.RaiseAndSetIfChanged(x=>x.IsSelected, value); }
   }
Run Code Online (Sandbox Code Playgroud)

<CheckBox IsChecked="{Binding IsSelected}">
Run Code Online (Sandbox Code Playgroud)

使用FolderViewModel稍微复杂一些,我将在稍后讨论逻辑。首先是Xaml,只需将当前的CheckBox声明替换为

<CheckBox IsThreeState="True" IsChecked="{Binding IsSelected}">
    <!--IsChecked = True, False or null-->
Run Code Online (Sandbox Code Playgroud)

因此,现在我们需要返回一组Nullable<bool>(aka bool?)。

public bool? IsSelected
{
   get
   { 
      if (SubFoldersAndFiles.All(x=>x.IsSelected) return true;
      if (SubFoldersAndFiles.All(x=>x.IsSelected==false) return false;
      return null;
   }
   set
   {
      // We can't set to indeterminate at folder level so we have to set to 
      // set to oposite of what we have now
      if(value == null)
         value = !IsSelected;

      foreach(var x in SubFoldersAndFiles)
          x.IsSelected = value;
   }
Run Code Online (Sandbox Code Playgroud)

或类似的东西...