调整大小后的WPF GridSplitter
使用gridsplitter调整网格大小后,当其他行折叠时,行*将不会回收空间 在一个包含三行的主详细视图中,我有以下网格。顶部的数据网格,中间的分割器和最后一行中的内容控制视图。拆分器上有一个关闭按钮,用于折叠细节。除了用户使用gridsplitter调整大小之外,这一切都可以正常工作调整大小后的WPF GridSplitter,wpf,xaml,gridsplitter,Wpf,Xaml,Gridsplitter,使用gridsplitter调整网格大小后,当其他行折叠时,行*将不会回收空间 在一个包含三行的主详细视图中,我有以下网格。顶部的数据网格,中间的分割器和最后一行中的内容控制视图。拆分器上有一个关闭按钮,用于折叠细节。除了用户使用gridsplitter调整大小之外,这一切都可以正常工作 <Grid Margin="3,0"> <Grid.RowDefinitions> <RowDefinition Height="*"/>
<Grid Margin="3,0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Style="{StaticResource CollapsableRow}"/><!-- Splitter Here -->
<RowDefinition Style="{StaticResource CollapsableRow}"/>
</Grid.RowDefinitions>
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>
就像我说的,除非使用gridsplitter来调整大小,否则折叠工作正常。在那之后,空白保持不变
编辑:
H.B.和Code裸体有简单而一致的建议,因此我尝试在数据触发器中不成功地实现它们:
<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>
如果使用GridSplitter,高度不再是自动的,而是具体的值。您需要使用样式或事件和代码隐藏手动更改回值,例如,双击可重置自动大小列:
private void columnspilter\u双击(对象发送器,鼠标按钮ventargs e)
{
如果(!ColumnTreeView.Width.IsAuto)ColumnTreeView.Width=new GridLength();
}
根据您提供的内容,GridSplitter将调整上一行和下一行的大小。您可以通过以下代码看到这一点:
<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>
最后一行的大小实际上将从“自动”更改为固定高度。因此,即使折叠该行中的内容,它仍将占用指定的空间。您需要将该行重置为
Height=“Auto”
,以使用其内容真正折叠该行。由于网格拆分器和细节已被隐藏,因此重置下一行定义高度的明显选择是可见性
/// <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);
}
}
//
///栅格拆分器,在拆分器的可见性更改时显示或隐藏以下行。
///
公共类HidableGridSplitter:GridSplitter{
网格长度和高度;
公共HidableGridSplitter()
{
this.IsVisibleChanged+=HideableGridSplitter\u IsVisibleChanged;
this.Initialized+=HideableGridSplitter_Initialized;
}
void HideableGridSplitter_已初始化(对象发送方,事件参数e)
{
//缓存初始行定义高度,
//因此,它并不总是假定为“自动”
Grid parent=base.parent为Grid;
if(parent==null)返回;
int rowIndex=Grid.GetRow(这个);
if(rowIndex+1>=parent.RowDefinitions.Count)返回;
var lastRow=parent.RowDefinitions[rowIndex+1];
高度=最后一行。高度;
}
void HideableGridSplitter_IsVisibleChanged(对象发送方,DependencyPropertyChangedEventArgs e)
{
Grid parent=base.parent为Grid;
if(parent==null)返回;
int rowIndex=Grid.GetRow(这个);
if(rowIndex+1>=parent.RowDefinitions.Count)返回;
var lastRow=parent.RowDefinitions[rowIndex+1];
if(this.Visibility==Visibility.Visible)
{
lastRow.高度=高度;
}
其他的
{
高度=最后一行。高度;
lastRow.Height=新网格长度(0);
}
}
您可以使用动画来解决gridsplitter的行/列定义覆盖问题。请参阅我在上对类似问题的回答我喜欢您和H.B.s的建议,并在行上执行了样式触发器:不起作用:(因为rowDefinition需要设置一个新的GridLength实例。@Ryan-我不确定我是否理解。如果设置this.row2.Height=GridLength.Auto;
,它将重置它。在代码中设置GridLength是需要做的。但是双击在这种情况下不起作用。正在设置网格拆分器的样式,它实际上是一个按钮。我选择覆盖网格拆分器,并在那里设置parent.hiegth。我的代码只是一个例子,我从来没有想到你在双击时不会做任何事情。