WPF GridSplitter после изменения размера
после того, как gridsplitter используется для изменения размера сетки строка * не будет освобождать пространство, когда другие строки свернуты.
у меня есть следующая сетка в главном подробном представлении с тремя строками. Сетка данных сверху разделитель посередине и представление contentcontrol в последней строке. Сплиттер имеет кнопку закрытия на нем, чтобы свернуть деталь. Все это работает за исключением того, что пользователь изменяет размер с помощью gridsplitter.
<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. И codenaked были простые и последовательные предложения, поэтому я попытался реализовать их без успеха в триггере данных:
<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>
4 ответов
поскольку разделитель сетки и детали уже были скрыты, видимость была очевидным выбором для сброса высоты определения следующей строки.
/// <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);
}
}
вы можете использовать анимацию для решения переопределения определения строки / столбца с помощью gridsplitter. См. мой ответ на аналогичный вопрос в GridSplitter переопределяет триггер стиля ColumnDefinition?
Если вы используете GridSplitter высоты больше не Auto
но конкретные значения. Вам нужно вручную изменить значения назад, используя стиль или события и код позади, например, это сбрасывает столбец автоматического размера при двойном щелчке:
private void ColumnSplitter_DoubleClick(object sender, MouseButtonEventArgs e)
{
if (!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>
размер последней строки фактически изменится с Auto на фиксированную высоту. Поэтому, даже если вы свернете содержимое в этой строке, оно все равно займет указанное пространство. Вам нужно будет сбросить строку до Height="Auto"
чтобы действительно свернуть его с его содержанием.