Как установить максимальную ширину столбца сетки в зависимости от размера окна или экрана в XAML

У меня есть сетка из 3 столбцов в окне с GridSplitter в первом столбце. Я хочу установить MaxWidth первого столбца равным трети родительского окна или страницы Width (или ActualWidth), и я бы предпочел сделать это в XAML, если это возможно.

Это пример XAML, с которым можно поиграть в XamlPad (или аналогичном), который показывает, что я делаю.

<Page xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:sys = "clr-namespace:System;assembly=mscorlib" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name = "Column1" Width = "200"/>
            <ColumnDefinition x:Name = "Column2" MinWidth = "50" />
            <ColumnDefinition x:Name = "Column3" Width = "{ Binding ElementName=Column1, Path=Width }"/>
            </Grid.ColumnDefinitions>

        <Label Grid.Column = "0" Background = "Green" />
        <GridSplitter Grid.Column = "0" Width = "5" />
        <Label Grid.Column = "1" Background = "Yellow" />
        <Label Grid.Column = "2" Background = "Red" />
    </Grid>
</Page>

Как видите, ширина правого столбца привязана к ширине первого столбца, поэтому, когда вы перемещаете левый столбец с помощью разделителя, правый столбец делает то же самое :) Если вы сдвинете левый столбец вправо, в конечном итоге он переместится на половину страницы / окна и переместится в правую часть окна, отодвигая столбцы 2 и 3.

Я хочу предотвратить это, установив MaxWidth столбца 1 равным трети ширины окна (или что-то в этом роде). Я могу сделать это в коде довольно легко, но как это сделать в «Только XAML»?

Обновлено: Дэвид Шмитт предложил использовать SharedSizeGroup вместо привязки, что является отличным предложением. Тогда мой пример кода будет выглядеть так:

<Page xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:sys = "clr-namespace:System;assembly=mscorlib" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" >
        <Grid IsSharedSizeScope = "True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name = "Column1" SharedSizeGroup = "ColWidth" Width = "40"/>
                <ColumnDefinition x:Name = "Column2" MinWidth = "50" Width = "*" />
                <ColumnDefinition x:Name = "Column3" SharedSizeGroup = "ColWidth"/>
            </Grid.ColumnDefinitions>
            <Label Grid.Column = "0" Background = "Green" />
            <GridSplitter Grid.Column = "0" Width = "5" />
            <Label Grid.Column = "1" Background = "Yellow" />
            <Label Grid.Column = "2" Background = "Red" />
        </Grid>
</Page>
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
0
28 832
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Слишком ленив, чтобы написать это самому, но у вас должна быть возможность использовать математический преобразователь и привязать к ширине родительских окон (либо по имени, либо с помощью поиска предков RelativeSource).

//I know I borrowed this from someone, sorry I forgot to add a comment from whom
public class ScaledValueConverter : IValueConverter
{
  public Object Convert(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
  {
     Double scalingFactor = 0;
     if (parameter != null)
     {
        Double.TryParse((String)(parameter), out scalingFactor);
     }

     if (scalingFactor == 0.0d)
     {
        return Double.NaN;
     }

     return (Double)value * scalingFactor;
  }

  public Object ConvertBack(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
  {
     throw new Exception("The method or operation is not implemented.");
  }
}
Ответ принят как подходящий

Я думаю, что подход, основанный только на XAML, несколько окольный, но вот способ сделать это.

<Page xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:sys = "clr-namespace:System;assembly=mscorlib"
      xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" >

    <!-- This contains our real grid, and a reference grid for binding the layout-->
    <Grid x:Name = "Container">

      <!-- hidden because it's behind the grid below -->
      <Grid x:Name = "LayoutReference">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width = "*"/>
          <ColumnDefinition Width = "*"/>
          <ColumnDefinition Width = "*"/>
        </Grid.ColumnDefinitions>
        <!-- We need the border, because the column doesn't have an ActualWidth -->
        <Border x:Name = "ReferenceBorder" 
                Background = "Black" />
        <Border Background = "White" Grid.Column = "1" />
        <Border Background = "Black" Grid.Column = "2" />
      </Grid>

      <!-- I made this transparent, so we can see the reference -->
      <Grid Opacity = "0.9">
          <Grid.ColumnDefinitions>
              <ColumnDefinition x:Name = "Column1" 
                                MaxWidth = "{Binding ElementName=ReferenceBorder,Path=ActualWidth}"/>
              <ColumnDefinition x:Name = "Column2" 
                                MinWidth = "50"  />
              <ColumnDefinition x:Name = "Column3" 
                                Width = "{ Binding ElementName=Column1, Path=Width }"/>
              </Grid.ColumnDefinitions>

          <Label Grid.Column = "0" Background = "Green"/>
          <GridSplitter Grid.Column = "0" Width = "5" />
          <Label Grid.Column = "1" Background = "Yellow" />
          <Label Grid.Column = "2" Background = "Red" />
      </Grid>
    </Grid>

</Page>

Используйте SharedSizeGroup вместо привязки к ширине другого столбца!

David Schmitt 04.10.2008 02:48

Я попробовал xaml выше в XamlPad, и он вёл себя как-то странно, но я понимаю вашу точку зрения! Спасибо.

Johan Danforth 09.10.2008 01:02

Другие вопросы по теме