2009-04-06 20 views
8

Quiero crear una mezcla de una vista en árbol y una vista de lista. Quiero tener 2 columnas. En la columna de la izquierda quiero una vista de árbol recursiva y la columna de la derecha debe mostrar información sobre los elementos de la columna de la izquierda. Llamemos a la columna izquierda Nombre y columna derecha Valor. El problema es que cuando expande una vista en árbol, el nivel de sangría cambia y la columna Valor se desalinea.WPF Vista en árbol con columnas de ancho fijo

Todo lo que puedo llegar a decir a cualquiera:

A: Utilice construido en TreeView y cambiar manualmente el ancho de la columna Nombre-dependiendo del nivel de sangrado por lo que el valor de la columna siempre está alineado.

B. Utilice el built-in ListView y cree manualmente un TreeView agregando elementos secundarios entre los elementos principales y también cambie la sangría de estos.

¿Realmente no hay una mejor manera?

Respuesta

6

Hay un propósito, tengo una bestia en una aplicación de Silverlight

Es necesario tweek la plantilla de la TreeViewItem. La plantilla predeterminada no se extiende a lo largo de la vista de árbol.

Al modificar la plantilla, puede hacer que se extienda hasta el final, y luego puede establecer su DataTemplate (o HierarchicalDataTemplate) en una cuadrícula. Si recuerdo correctamente, debe obtener una copia de la plantilla predeterminada del TreeviewItem y cambiar la propiedad HorizontalAlignment del elemento "Header" a "Stretch", eliminar la columna más a la derecha en la cuadrícula que compone la plantilla y cambiar la ancho de la columna que contiene el elemento de "Auto" a "*".

Es bastante fácil de hacer usando blend. Cree un TreeViewItem, haga clic derecho sobre él y seleccione "editar partes de control (" Plantilla ")> Editar una copia ..." Esto creará una copia de la plantilla predeterminada para TreeViewItem. Desde allí, ubique el ContentPresenter llamado PART_Header. Al pasar de esto, encuentre la cuadrícula que contiene y modifique sus columnas para que coincida con mi explicación (elimine la última columna, cambie la segunda columna de "Auto" a "*"). En el Estilo que se creó para el elemento, configure HorizontalContentAlignment en "Estirar" (está vinculado a otra cosa por defecto).

Utilice el estilo que se creó como ItemContainerStyle en la vista de árbol. Puede eliminar TreeViewItem que creó al principio después de eso.

Al final, usted terminará con muchos recursos, uno de los cuales es su estilo. Vea a continuación para lo que acabo (tanto el estilo TreeViewItem como un DataTemplate básico para mis elementos con un nombre y columnas de valor). Se crearon otros recursos que la referencia de estilo/plantilla de TreeViewItem, pero no se muestran aquí (porque ya es demasiado larga: p).

<Window.Resources>  
<Style x:Key="TreeViewItemStyle1" TargetType="{x:Type TreeViewItem}"> 
     <Setter Property="Background" Value="Transparent"/> 
     <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
     <Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> 
     <Setter Property="Padding" Value="1,0,0,0"/> 
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
     <Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type TreeViewItem}"> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition MinWidth="19" Width="Auto"/> 
          <ColumnDefinition Width="*"/> 
         </Grid.ColumnDefinitions> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="Auto"/> 
          <RowDefinition/> 
         </Grid.RowDefinitions> 
         <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" ClickMode="Press" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"/> 
         <Border x:Name="Bd" SnapsToDevicePixels="true" Grid.Column="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> 
          <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" x:Name="PART_Header" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header"/> 
         </Border> 
         <ItemsPresenter x:Name="ItemsHost" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1"/> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsExpanded" Value="false"> 
          <Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/> 
         </Trigger> 
         <Trigger Property="HasItems" Value="false"> 
          <Setter Property="Visibility" TargetName="Expander" Value="Hidden"/> 
         </Trigger> 
         <Trigger Property="IsSelected" Value="true"> 
          <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> 
          <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/> 
         </Trigger> 
         <MultiTrigger> 
          <MultiTrigger.Conditions> 
           <Condition Property="IsSelected" Value="true"/> 
           <Condition Property="IsSelectionActive" Value="false"/> 
          </MultiTrigger.Conditions> 
          <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> 
          <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
         </MultiTrigger> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

     <HierarchicalDataTemplate x:Key="DataTemplate1"         
            ItemsSource="{Binding SubNodes}"> 
      <Grid Margin="5"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="Auto" /> 
        <ColumnDefinition Width="*"/> 
        <ColumnDefinition Width="Auto" /> 
       </Grid.ColumnDefinitions> 
       <TextBlock HorizontalAlignment="Left" 
          VerticalAlignment="Top" 
          Grid.Column="1" 
          Text="HEADER" 
          TextWrapping="Wrap" /> 
       <TextBox HorizontalAlignment="Left" 
         Margin="2" 
         VerticalAlignment="Top" 
         Text="VALUE" 
         TextWrapping="Wrap" 
         Grid.Column="2" /> 
      </Grid> 

</Window.Resources> 

<TreeView HorizontalAlignment="Stretch" 
        VerticalAlignment="Stretch" 
        Width="Auto" 
        Height="Auto" 
        x:Name="trv" 
      ItemContainerStyle="{StaticResource TreeViewItemStyle1}" 
        ItemTemplate="{DynamicResource DataTemplate1}">    
     </TreeView> 

Tenga en cuenta que necesita para asegurarse de que sus columnas de la cuadrícula que contienen las células a la derecha será siempre la misma anchura, de lo contrario tendrá algo raro (utilizo columnas "Auto" con un contenido de ancho fijo, y Agrego una columna en blanco "*" entre el nombre y las "celdas" para alinearlos a la derecha).

También tenga en cuenta que esta solución básicamente "congela" la apariencia de la vista de árbol para cualquier tema que tenga en su máquina. (Se verá igual en una máquina con Vista y XP, según el sistema operativo que utilizó al realizar la modificación).

Cuestiones relacionadas