Как свернуть столбец сетки размера звезды в WPF?

Получение трех столбцов одинаковой ширины осуществляется настройкой Width в Auto,

<Grid x:Name="myGrid">
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>

  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition Width="*" />
    <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>

  <Label Grid.Row="0" Grid.Column="0">One</Label>
  <Label Grid.Row="0" Grid.Column="1" x:Name="label1">Two</Label>
  <Label Grid.Row="0" Grid.Column="2">Three</Label>
</Grid>

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

Если я просто установил Видимость на Свернутый или Скрытый из-за ширины ="*", ширина двух других столбцов останется прежней.

<Label Grid.Row="0" Grid.Column="1" Visibility="Collapsed">Two</Label>

введите описание изображения здесь

Я достиг желаемой функциональности, программно установив ширину второго столбца в автоматический, но я ищу другое решение (предпочтительно способ xaml один).

private void Button_Click(object sender, RoutedEventArgs e)
{
  this.myGrid.ColumnDefinitions[1].Width = GridLength.Auto;
  this.label1.Visibility = Visibility.Collapsed;
}

3 ответа

Желаемое поведение может быть достигнуто с помощью UniformGrid.

Обязательно установите количество строк равным 1.

      <UniformGrid Rows="1">
    <Label>One</Label>
    <Label>Two</Label>
    <Label>Three</Label>
</UniformGrid>

Остальные элементы расположены равномерно.

      <UniformGrid Rows="1">
    <Label>One</Label>
    <Label Visibility="Collapsed">Two</Label>
    <Label>Three</Label>
</UniformGrid>

Я добавил Xaml Binding, как предложил Роб:

<Grid.ColumnDefinitions>
  <ColumnDefinition Width="*" />
  <ColumnDefinition Width="{Binding MiddleColumnWidth}" />
  <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<Label Grid.Row="0" Grid.Column="0">One</Label>
<Label Grid.Row="0" Grid.Column="1" Visibility="{Binding IsSecondLabelVisible}">Two</Label>
<Label Grid.Row="0" Grid.Column="2">Three</Label>

Код позади xaml:

private bool ShowOnlyTwoColumns;

private GridLength MiddleColumnWidth
{
  get
  {
    if (ShowOnlyTwoColumns)
      return GridLength.Auto; // Auto collapses the grid column when label is collapsed

    return new GridLength(1, GridUnitType.Star);
  }
}

private Visibility IsSecondLabelVisible
{
  get { return this.ShowOnlyTwoColumns ? Visibility.Collapsed : Visibility.Visible; }
}

Я опаздываю, но хочу представить свое решение, вдруг оно кому-нибудь пригодится.

Я использую этот конвертер

      public class BooleanToAutoOrStarGridLengthConverter : MarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool isStar)
            return new GridLength(1, isStar ? GridUnitType.Star : GridUnitType.Auto);
        return new GridLength(0, GridUnitType.Star);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is GridLength gridLength && gridLength.GridUnitType == GridUnitType.Star)
            return true;
        return false;
    }

    public override object ProvideValue(IServiceProvider serviceProvider) => this;
} 

в XAML вот так:

      <Grid.ColumnDefinitions>
  <ColumnDefinition Width="*" />
  <ColumnDefinition Width="{Binding IsSecondLabelVisible, Converter={BooleanToAutoOrStarGridLengthConverter}}" />
  <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<Label Grid.Row="0" Grid.Column="0">One</Label>
<Label Grid.Row="0" Grid.Column="1" Visibility="{Binding IsSecondLabelVisible}">Two</Label>
<Label Grid.Row="0" Grid.Column="2">Three</Label>
Другие вопросы по тегам