WPF: последнее видимое дочернее заполнение DockPanel?

Поведение, которое я ищу, в основном похоже на DockPanel, я хотел бы, чтобы последний ребенок заполнил доступное пространство. Подвох в том, что я хотел бы, чтобы это был последний видимый ребенок. В моем случае у меня есть два представления, которые я хотел бы отображать рядом.

До сих пор я пробовал применять к сетке два разных стиля, но ни один из них не работает. Я также пытался использовать конвертер, который, казалось, работал в теории (я смог вернуть «Авто», используя double.NaN), но я не был уверен, как вернуть ширину «*» из кода.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*">
            <ColumnDefinition.Style>
                <Style TargetType="{x:Type ColumnDefinition}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Visibility, ElementName=ccSomeItems}" Value="Collapsed">
                            <Setter Property="Width" Value="0" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ColumnDefinition.Style>
        </ColumnDefinition>
        <ColumnDefinition Width="*">
            <ColumnDefinition.Style>
                <Style TargetType="{x:Type ColumnDefinition}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding SomeOtherItems.AllOtherItems.Count, Converter={StaticResource IntegerToVisibilityConverter}}" Value="Collapsed">
                            <Setter Property="Width" Value="0" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ColumnDefinition.Style>
        </ColumnDefinition>
    </Grid.ColumnDefinitions>
    <ContentControl x:Name="ccSomeItems" Content="{Binding SomeItems}" Margin="4" Visibility="{Binding SomeItems.AllItems.Count, Converter={StaticResource IntegerToVisibilityConverter}}" />
    <ContentControl Grid.Column="1" Content="{Binding SomeOtherItems}" Margin="4" Visibility="{Binding SomeOtherItems.AllOtherItems.Count, Converter={StaticResource IntegerToVisibilityConverter}}" />
</Grid>

person Derrick Moeller    schedule 15.09.2014    source источник
comment
Я в замешательстве... почему вы используете Grid вместо DockPanel, если вам нужно поведение DockPanel? Кроме того, вы можете использовать тип единицы измерения GridUnitType.Star, чтобы указать размеры звездочек в коде, например: new GridLength(2, GridUnitType.Star)   -  person Rachel    schedule 15.09.2014
comment
Я использую Grid для создания поведения, которого нет в DockPanel (насколько мне известно). Как я уже сказал, проблема в том, что я хотел бы заполнить последний видимый дочерний элемент. Я буду исследовать класс GridLength.   -  person Derrick Moeller    schedule 15.09.2014


Ответы (2)


Мне удалось просмотреть комментарий Рэйчел и найти решение с помощью конвертера.

XAML:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="{Binding Visibility, ElementName=SomeItems, Converter={StaticResource VisibilityToGridLengthConverter}}" />
        <ColumnDefinition Width="{Binding Visibility, ElementName=SomeOtherItems, Converter={StaticResource VisibilityToGridLengthConverter}}" />
    </Grid.ColumnDefinitions>
    <ContentControl x:Name="SomeItems" Content="{Binding SomeItems}" Visibility="{Binding SubPackages.AllPackages.Count, Converter={StaticResource IntegerToVisibilityConverter}}" />
    <ContentControl x:Name="SomeOtherItems" Grid.Column="1" Content="{Binding SomeOtherItems}" Visibility="{Binding Elements.AllElements.Count, Converter={StaticResource IntegerToVisibilityConverter}}" />
</Grid>

И конвертер:

[ValueConversion(typeof(Visibility), typeof(GridLength))]
public class VisibilityToGridLengthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (Visibility)value == Visibility.Collapsed ? new GridLength(0) : new GridLength(1, GridUnitType.Star);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
person Derrick Moeller    schedule 17.09.2014

Я нашел более простое решение, заключающееся в том, чтобы просто окружить элементы, которые вы хотите заполнить доступным пространством, с помощью элемента сетки. Таким образом, сетка становится последним элементом, который всегда заполняет доступное пространство. Видимость элементов управления в сетке может быть настроена так, как они хотят.

    <DockPanel Height="31" HorizontalAlignment="Left" Margin="82,107,0,0" Name="dockPanel1" VerticalAlignment="Top" Width="286" LastChildFill="True">
  <TextBlock Text="Text block" DockPanel.Dock="Left" />
  <Grid>
    <Button Content="Button1" Visibility="Visible" />
    <Button Content="Button2" Visibility="Collapsed" />
  </Grid>
</DockPanel>
person GWR    schedule 21.12.2018