Ограничить высоту строки как для Auto, так и для 1 * в WPF

У меня есть приложение WPF, макет которого состоит из 3 строк на верхнем уровне Grid.

Я хочу, чтобы средний ряд использовал необходимое пространство (максимальное необходимое пространство ограничено, но зависит от ширины окна). Нижний ряд должен использовать оставшееся пространство. Сложная часть — верхний ряд. Его размер может варьироваться в зависимости от кнопки, которая переключает видимость большей части содержимого. Я хочу, чтобы он использовал не более 50% высоты, но не больше, чем ему действительно нужно. Следующий XAML описывает, что я хочу сделать:

    <Grid.RowDefinitions>
        <!-- neither "1*" nor "Auto" fully meets my needs -->
        <RowDefinition Height="Min(1*,Auto)"></RowDefinition>

        <RowDefinition Height="Auto"></RowDefinition>

        <RowDefinition Height="1*"></RowDefinition>
    </Grid.RowDefinitions>

Ряды:

  1. WrapPanel
  2. WrapPanel
  3. TextBox

если это важно.


person Onur    schedule 13.12.2012    source источник


Ответы (3)


Если я правильно понимаю, вы, вероятно, могли бы использовать Auto, а затем привязать атрибут MaxHeight к Height атрибута Grid. Может быть, что-то вроде этого:

MaxHeightConverter.cs:

public class MaxHeightConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            throw new ArgumentException("MaxHeightConverter expects a height value", "values");

        return ((double)value / 2);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

MyWindow.xaml:

...
xmlns:converters="clr-namespace:MyApp.Namespace"
...
<Window.Resources>
    <converters:MaxHeightConverter x:Key="MaxHeightValue" />
</Window.Resources>

<Grid x:Name="root">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="1*"></RowDefinition>
    </Grid.RowDefinitions>

    <WrapPanel >
        <WrapPanel.MaxHeight>
            <Binding Converter="{StaticResource MaxHeightValue}" ElementName="root" Path="ActualHeight" />
        </WrapPanel.MaxHeight>
    </WrapPanel>
</Grid>
...

Надеюсь это поможет.

person JGaarsdal    schedule 13.12.2012
comment
Спасибо. Работает именно так, как я хочу. Мне просто нужно было изменить актерский состав с (int) на (double) в MaxHeightConverter. - person Onur; 13.12.2012

Другой способ, которым вы могли бы сделать это только с помощью XAML, - это привязка к скрытому объекту той высоты, которую вы хотите:

<Grid>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
        <Border Background="White" Visibility="Hidden" x:Name="HalfHeightRow" x:FieldModifier="private" />
    </Grid>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Border Height="1000" Background="Red" MaxHeight="{Binding ActualHeight, ElementName=HalfHeightRow}" />
        <Border Grid.Row="1" Height="100" Background="Green" />
        <Border Grid.Row="2" Background="Blue" />
    </Grid>

person Matt Holcomb    schedule 13.12.2012
comment
Интересный подход. Это может быть полезно для меня в более сложных ситуациях. Но пока я буду придерживаться решения Jespers. - person Onur; 13.12.2012

Вы могли бы сделать предложение Мэтта еще проще и яснее.

<Grid>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*" x:Name="HalfHeightRow"/>
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
    </Grid>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" MaxHeight="{Binding ActualHeight, ElementName=HalfHeightRow}"/>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Border Height="1000" Background="Red" />
        <Border Grid.Row="1" Height="100" Background="Green" />
        <Border Grid.Row="2" Background="Blue" />
    </Grid>
person kphil80    schedule 28.11.2018