2011-06-20 23 views
23

Có một số ví dụ về cách điền chế độ xem dạng cây từ tập hợp các đường dẫn tệp chẳng hạn như ví dụ this hoặc this other. Tôi dường như không thể tìm thấy ví dụ như vậy cho WPF. Tôi biết tôi có thể tích hợp các hình thức cửa sổ và sử dụng một điều khiển khác nhau để làm cho nó hoạt động nhưng nó sẽ được tốt đẹp nếu tôi có thể làm điều tương tự với một điều khiển wpf treeview. Chế độ xem dạng cây mà tôi muốn xây dựng bao gồm khoảng 50.000 tệp vì vậy tôi nghĩ rằng nó sẽ tốt hơn nếu nó liên kết nó với một cái gì đó. Nhưng trước khi ràng buộc nó, tôi nghĩ rằng nó sẽ rất hữu ích để xây dựng một dựa trên một danh sách các chuỗi (chuỗi chứa các đường dẫn của các tập tin).điền vào số treeview từ danh sách đường dẫn tệp trong wpf

+1

Bạn sẽ không phải điền toàn bộ bộ sưu tập trước. Bạn có thể có kiểm soát cây lấy theo yêu cầu. Tôi đã sử dụng điều khiển cây teleriks cho việc này. –

Trả lời

53

Tôi đã bị cuốn hút bởi câu hỏi và đã ném điều này lại với nhau. Lần đầu tiên tôi nghĩ rằng tôi khá gần với những gì bạn đang tìm kiếm. Nói về 50.000 mặt hàng mặc dù làm cho tôi nghĩ rằng tải lười biếng có thể thích hợp. Dù sao, đây là phiên bản đơn giản dựa trên một số article bởi Josh Smith. Tôi đặt tất cả các mã ở đây, nhưng phép thuật thực sự diễn ra với các mẫu dữ liệu.

Cho một vài lớp học để đại diện cho các đối tượng chúng tôi đang làm việc với ...

using System.Collections.Generic; 

namespace WpfTreeViewBinding.Model 
{ 
    public class Item 
    { 
     public string Name { get; set; } 
     public string Path { get; set; } 
    } 
} 

và ...

namespace WpfTreeViewBinding.Model 
{ 
    public class FileItem : Item 
    { 

    } 
} 

và ...

namespace WpfTreeViewBinding.Model 
{ 
    public class DirectoryItem : Item 
    { 
     public List<Item> Items { get; set; } 

     public DirectoryItem() 
     { 
      Items = new List<Item>(); 
     } 
    } 
} 

tôi đã tạo phương thức đệ quy để tải lên một số thư mục/tệp ...

using System.Collections.Generic; 
using System.IO; 
using WpfTreeViewBinding.Model; 

namespace WpfTreeViewBinding 
{ 
    public class ItemProvider 
    { 
     public List<Item> GetItems(string path) 
     { 
      var items = new List<Item>(); 

      var dirInfo = new DirectoryInfo(path); 

      foreach(var directory in dirInfo.GetDirectories()) 
      { 
       var item = new DirectoryItem 
           { 
            Name = directory.Name, 
            Path = directory.FullName, 
            Items = GetItems(directory.FullName) 
           }; 

       items.Add(item); 
      } 

      foreach(var file in dirInfo.GetFiles()) 
      { 
       var item = new FileItem 
           { 
            Name = file.Name, 
            Path = file.FullName 
           }; 

       items.Add(item); 
      } 

      return items; 
     } 
    } 
} 

Từ đó nó chỉ là một vấn đề nhận được dữ liệu ...

using System.Windows; 

namespace WpfTreeViewBinding 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      var itemProvider = new ItemProvider(); 

      var items = itemProvider.GetItems("C:\\Temp"); 

      DataContext = items; 
     } 
    } 
} 

Và hiển thị nó ...

<Window x:Class="WpfTreeViewBinding.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:Model="clr-namespace:WpfTreeViewBinding.Model" 
     Title="MainWindow" 
     Height="350" Width="525"> 

    <Window.Resources> 

     <HierarchicalDataTemplate DataType="{x:Type Model:DirectoryItem}" 
            ItemsSource="{Binding Items}"> 
      <TextBlock Text="{Binding Path=Name}" ToolTip="{Binding Path=Path}" /> 
     </HierarchicalDataTemplate> 

     <DataTemplate DataType="{x:Type Model:FileItem}"> 
      <TextBlock Text="{Binding Path=Name}" ToolTip="{Binding Path=Path}" /> 
     </DataTemplate> 

    </Window.Resources> 

    <Grid Margin="8"> 
     <TreeView ItemsSource="{Binding}" /> 
    </Grid> 

</Window> 

Tất cả sự kỳ diệu thực sự xảy ra với các mẫu dữ liệu. Tôi đoán chìa khóa để toàn bộ điều đang sử dụng HierarchicalDataTemplate cho bất kỳ mục nào có phân cấp (tức là thư mục).

LƯU Ý 1: Tôi chưa thử nghiệm rộng rãi điều này. Nó đã không được lược tả cho hiệu suất. Tôi sẽ hoan nghênh bất kỳ thông tin phản hồi mặc dù vì đây là một vấn đề tôi đã cố gắng để giải quyết từ lâu và từ bỏ. Cảm ơn!

CHÚ Ý 2: Bạn sẽ cần phải đặt đường dẫn mã hóa cứng thành đường dẫn có ý nghĩa trên hệ thống của bạn.

Dưới đây là một bức ảnh chụp thư mục và các tập tin ở các cấp độ khác nhau ...

enter image description here

+0

Jhon cảm ơn rất nhiều! câu trả lời của bạn sẽ rất tuyệt. Tôi rất mong được thử nghiệm giải pháp của bạn khi tôi trở lại vào sáng mai. Đừng làm việc trong bất kỳ chỉnh sửa nào nữa ... Hãy để tôi thử nghiệm nó trước. –

+4

Đây là câu trả lời hay. Tuy nhiên, không cần tạo một lớp Item và FileItem. Bạn có thể tạo một DataTemplate cục bộ cho cả hai hệ thống.Các lớp DirectoryInfo và FileInfo IO. –

+0

Bây giờ hãy tăng cường nó để sử dụng tải chậm:] – cordialgerm

3

phần mở rộng nhỏ cho giải pháp trước: tôi thêm mã XAML để hỗ trợ các biểu tượng, và hỗ trợ cho chuyển đổi giữa các biểu tượng cho thư mục đã mở và đóng:

<HierarchicalDataTemplate DataType="{x:Type viewModels:SourceControlDirecoryViewModel}" 
            ItemsSource="{Binding Items}"> 
      <Grid> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="Auto" /> 
        <ColumnDefinition Width="5" /> 
        <ColumnDefinition Width="*" /> 
       </Grid.ColumnDefinitions> 
       <Image Width="16" 
         Height="16" 
         Source="{StaticResource ImageSourceFolderClosed16x16}" 
         x:Name="img" /> 
       <TextBlock Text="{Binding Path=Name}" 
          ToolTip="{Binding Path=Path}" 
          Grid.Column="2" /> 
      </Grid> 
      <DataTemplate.Triggers> 
       <DataTrigger Binding="{Binding IsExpanded, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type TreeViewItem}}}" 
          Value="True"> 
        <Setter Property="Source" 
          TargetName="img" 
          Value="{StaticResource ImageSourceFolderOpened16x16}" /> 
       </DataTrigger> 
      </DataTemplate.Triggers> 
     </HierarchicalDataTemplate> 
Các vấn đề liên quan