0

我正在尝试创建具有以下层次结构的 TreeView:

Device1
--File1
--File2
--Hook1
--Hook2
Device2
--File1
--File1
Device3
--Hook1

所以基本上根级别节点是一个设备,其子节点是文件和钩子。我使用分层数据模板创建了以下树

<TreeView ItemsSource="{Binding Devices}">
        <HierarchicalDataTemplate DataType="{x:Type datamodel:Device}" ItemsSource="{Binding Files}">
               <TextBlock Margin="5,5,0,0" Text="{Binding DeviceName}"/>
                  <HierarchicalDataTemplate.ItemTemplate>
                       <DataTemplate  DataType="{x:Type datamodel:File}">
                            <TextBlock Margin="5,0,0,0" Text="{Binding FileName}"/>
                        </DataTemplate>
                 </HierarchicalDataTemplate.ItemTemplate>
       </HierarchicalDataTemplate>

     Class Devices
     {

          public string DeviceName
          {
             get;set;
          }

          public string List<File> Files
          {
              get;set;
          }

         public string List<Hook> Hooks
          {
              get;set;
          }
     }

  public class File
{
     public string FileName
     {
        get;set;
     }


     public string FileType
    {
        get;set;
    }

    public string Location
    {
        get; set;
    }

}


public class Hook
{
    public string HookName
    {
       get;set;
    }

    public string Type
   {
      get;set;
   }
}

我只能在 HierarchicalDataTemplate 的 ItemTemplate 中添加一个数据模板。如何在单个 HierarchicalDataTemplate 下指定两种数据类型?

4

2 回答 2

0

您必须在此处使用转换器,该转换器将返回CompositeCollection包含文件和挂钩的转换器。您将使用此转换ItemsSourceHierarchicalDataTemplate DataType="{x:Type datamodel:Device}"

然后你只需要为 File 和 Hook 数据类型定义两个数据模板。

谢谢

于 2013-08-29T17:47:03.433 回答
0

我尝试使用 CompositeCollection,但意识到绑定的对象已转换为基本类型。所以我将它与 DataTemplateSelector 结合使用。以下解决方案对我有用。

<TreeView ItemsSource="{Binding Devices}">
     <TreeView.Resources>
       <HierarchicalDataTemplate DataType="{x:Type datamodel:Devices}" ItemTemplateSelector="{StaticResource LeafDataTemplateSelector}">
            <HierarchicalDataTemplate.ItemsSource>
                 <MultiBinding Converter="{StaticResource CompositeCollectionConverter}">
                      <Binding Path="Files" />
                      <Binding Path="Hooks"/>
                 </MultiBinding>
            </HierarchicalDataTemplate.ItemsSource>
                <StackPanel Height="25" Orientation="Horizontal">
                   <Image Height="20" Width="20" Source="Device.png"/>
                    <TextBlock Margin="5,5,0,0" Text="{Binding Device}"/>
                </StackPanel>
           </HierarchicalDataTemplate>

         <DataTemplate x:Key="FileKey" DataType="{x:Type datamodel:File}">
                <StackPanel Height="25" Orientation="Horizontal" ToolTip="Installation File">
                     <Image Height="20" Width="20" Source="File.png" />
                      <TextBlock Text="{Binding FileName}"/>
                </StackPanel>
         </DataTemplate>
         <DataTemplate x:Key="HookKey"  DataType="{x:Type datamodel:Hook}">
               <StackPanel Height="25" Orientation="Horizontal"  ToolTip="Installation Hook">
                   <Image Height="20" Width="20" Source="Hook.png" />
                   <TextBlock Margin="5,5,0,0" Text="{Binding HookName}"/>
               </StackPanel>
         </DataTemplate>
    </TreeView.Resources>

已经使用模板选择器根据键选择合适的模板。

 public class LeafDataTemplateSelector :  DataTemplateSelector
{
    public override DataTemplate
        SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        if (element != null && item != null)
        {

            if (item is InstallationManifesFile)
                return
                        element.FindResource("FileKey")
                        as DataTemplate;
            else if (item is InstallationManifestHook)
                return element.FindResource("HookKey")
                        as DataTemplate;
        }

        return null;
    }
}

public class CompositeCollectionConverter : IMultiValueConverter
{

    public object Convert(object[] values
        , Type targetType
        , object parameter
        , System.Globalization.CultureInfo culture)
    {
        var res = new CompositeCollection();
        foreach (var item in values)
            if (item is IEnumerable && item != null)
                res.Add(new CollectionContainer()
                {
                    Collection = item as IEnumerable
                });
        return res;
    }

    public object[] ConvertBack(object value
        , Type[] targetTypes
        , object parameter
        , System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
于 2013-10-25T11:51:07.777 回答