2011-05-10 14 views
6

Una vez que el gridsplitter se utiliza para cambiar el tamaño de una cuadrícula de la fila * no va a recuperar el espacio cuando se contraen las otras filas.WPF GridSplitter después de cambiar el tamaño de

I tienen la siguiente rejilla en una vista de detalle principal con tres filas. Una cuadrícula de datos en la parte superior de un divisor en el medio y una vista de control de contenido en la última fila. El divisor tiene un botón de cierre para colapsar el detalle. Todo esto funciona con la excepción de que una vez que el usuario cambia el tamaño usando el divisor de grillas.

<Grid Margin="3,0"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*"/> 
     <RowDefinition Style="{StaticResource CollapsableRow}"/><!-- Splitter Here --> 
     <RowDefinition Style="{StaticResource CollapsableRow}"/> 
    </Grid.RowDefinitions> 

El estilo GridSplitter:

<Style x:Key="gridSplitterStyle" TargetType="{x:Type GridSplitter}"> 
    <Setter Property="Visibility" Value="{Binding IsItemSelected, Converter={StaticResource BoolToShow},ConverterParameter='Visible|Collapsed'}" /> 
    <Setter Property="Width" Value="Auto"/> 
    <Setter Property="Height" Value="14"/> 
    <Setter Property="HorizontalAlignment" Value="Stretch"/> 
    <Setter Property="Border.BorderBrush" Value="#FF6593CF" /> 
    <Setter Property="Border.BorderThickness" Value="0,1,0,0" /> 
    <Setter Property="UIElement.SnapsToDevicePixels" Value="True" /> 
    <Setter Property="UIElement.Focusable" Value="False" /> 
    <Setter Property="Control.Padding" Value="7,7,7,7" /> 
    <Setter Property="Cursor" Value="SizeNS" /></Style> 

Como dije el colapso funciona correctamente a menos que el gridsplitter se utiliza para cambiar el tamaño. Después de eso, el espacio en blanco permanece.

EDIT: H. B. y codenaked tenido sugerencias simples y por lo consistant y he tratado de ponerlas en práctica w/o el éxito en un activador de datos:

<Style x:Key="CollapsableRow" TargetType="{x:Type RowDefinition}"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding SelectedItem, Converter={StaticResource IsNullConverter}}" Value="True"> 
      <Setter Property="RowDefinition.Height" Value="0"/> 
     </DataTrigger> 
     <DataTrigger Binding="{Binding SelectedItem, Converter={StaticResource IsNullConverter}}" Value="False"> 
      <Setter Property="RowDefinition.Height" Value="Auto"/> 
     </DataTrigger>    
    </Style.Triggers> 
</Style> 

Respuesta

6

Visibilidad Desde el separador de rejilla y el detalle ya estaban siendo escondidos fue la elección obvia para restablecer la siguiente definición altura de la fila.

/// <summary> 
/// Grid splitter that show or hides the following row when the visibility of the splitter is changed. 
/// </summary> 
public class HidableGridSplitter : GridSplitter { 

    GridLength height; 

    public HidableGridSplitter() 
    { 
     this.IsVisibleChanged += HideableGridSplitter_IsVisibleChanged; 
     this.Initialized += HideableGridSplitter_Initialized; 
    } 

    void HideableGridSplitter_Initialized(object sender, EventArgs e) 
    { 
     //Cache the initial RowDefinition height, 
     //so it is not always assumed to be "Auto" 
     Grid parent = base.Parent as Grid; 
     if (parent == null) return; 
     int rowIndex = Grid.GetRow(this); 
     if (rowIndex + 1 >= parent.RowDefinitions.Count) return; 
     var lastRow = parent.RowDefinitions[rowIndex + 1]; 
     height = lastRow.Height; 
    } 

    void HideableGridSplitter_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     Grid parent = base.Parent as Grid; 
     if (parent == null) return; 

     int rowIndex = Grid.GetRow(this); 

     if (rowIndex + 1 >= parent.RowDefinitions.Count) return; 

     var lastRow = parent.RowDefinitions[rowIndex + 1]; 

     if (this.Visibility == Visibility.Visible) 
     { 
      lastRow.Height = height; 
     } 
     else 
     { 
      height = lastRow.Height; 
      lastRow.Height = new GridLength(0); 
     } 

    } 
1

Si utiliza el GridSplitter las alturas ya no son Auto pero hormigón valores. Debe volver a cambiar manualmente los valores utilizando un estilo o eventos y un código detrás, p. Ej. esto restablece una columna de tamaño automático en el doble click:

private void ColumnSplitter_DoubleClick(object sender, MouseButtonEventArgs e) 
{ 
    if (!ColumnTreeView.Width.IsAuto) ColumnTreeView.Width = new GridLength(); 
} 
+0

Ajuste del gridlength en el código es lo que hay que hacer. Sin embargo, el doble clic no va a funcionar en este caso. El divisor de cuadrícula está siendo diseñado y es realmente un botón en el divisor que cierra. Elijo anular el divisor de cuadrícula y establecer el parent.hiegth allí. –

+0

Mi código era solo un ejemplo, nunca esperé que no hiciera nada en 'DoubleClick'. –

0

Sobre la base de lo que ya ha proporcionado, la GridSplitter cambiará el tamaño de las filas anteriores y siguientes. Esto se puede ver en acción con este código: tamaño

<Grid Margin="3,0"> 
    <Grid.RowDefinitions> 
     <RowDefinition x:Name="row0" Height="*" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition x:Name="row2" Height="Auto" /> 
    </Grid.RowDefinitions> 
    <Border Background="Red" > 
     <TextBlock Text="{Binding ElementName=row0, Path=Height}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
    </Border> 
    <GridSplitter Grid.Row="1" Style="{StaticResource gridSplitterStyle}" HorizontalAlignment="Stretch" /> 
    <Border Background="Blue" Grid.Row="2" MinHeight="50"> 
     <TextBlock Text="{Binding ElementName=row2, Path=Height}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
    </Border> 
</Grid> 

El último de la fila cambiará realmente de Auto a una altura fija. Por lo tanto, incluso si contrae el contenido en esa fila, aún ocupará el espacio especificado. Debería restablecer la fila al Height="Auto" para colapsarla realmente con su contenido.

+0

Me gustan su y H.B. s suggetion y implmented un disparador de estilo en la fila para hacerlo: –

+0

no funcionó :(sincee la rowDefinition necesita una nueva instancia de GridLength ser establecido –

+0

@Ryan - No estoy seguro de entender Si establece 'this.row2.. .Height = GridLength.Auto; 'luego lo restablecería. – CodeNaked

Cuestiones relacionadas