Сетка внутри StackPanel: почему авто и * ведут себя странно?

Мой google и stackoverflow search-fu мне не удалось, поэтому я предлагаю сообществу этот вопрос.

(Все это сгенерировано с использованием VS2010 и .NET 4.0 в пустом решении WPF по умолчанию)

Рассмотрим следующий XAML:

<StackPanel Orientation="Horizontal">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="20"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Border Name="aborder" Grid.Column="0" Grid.ColumnSpan="2" 
                    Background="Red" Width="200"/>
        <Border Name="aborder2" Background="Green"/>

    </Grid>
</StackPanel>

Что бы вы предсказывали ширину "aborder2"?

Если вы догадались "20 пикселей", вы ошибаетесь. Правильный ответ - 110 пикселей.

Рассмотрим этот XAML:

    <StackPanel Orientation="Horizontal">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="20"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

        <Border Name="aborder" Grid.Column="0" Grid.ColumnSpan="2" 
                    Background="Red" Width="200"/>
        <Border Name="aborder2" Background="Green"/>

    </Grid>
</StackPanel>

Что бы вы предсказывали ширину "aborder2"?

Если вы угадали либо 20 пикселей, либо 110 пикселей, вы ошибались. Правильный ответ - 200 пикселей.

Я не могу понять это, и это сводит меня с ума. Кажется, ответ должен быть очевиден; ясно, что существует некоторое взаимодействие между столбцом сетки автозаполнения и панелью стека, которая заставляет сетку волноваться. Но это просто не имеет смысла - все правила, регулирующие такое поведение, кажутся произвольными. Почему 110 пикселей? Почему не 109 пикселей или 100 пикселей? Я бы понял, если столбец с автоматическим размером не смог полностью или что-то расширить, но чтобы столбец фиксированной ширины беспорядочно игнорировал его ширину, я оставил обожженную оболочку разработчика.

Любые помощь или направляющие огни будут высоко оценены!

Ответ 1

Я понятия не имею, почему первый пример не правильно отображается

Вторая причина в том, что Auto означает "тот же размер, что и содержимое", но в столбце 2 ничего нет, поэтому Column2 получает рендеринг на 0px. У вас есть что-то в столбце 1, которое охватывает 2 ячейки, но так как Column2 отображается в 0 px, это означает, что Column1 растягивается до 200 px. По умолчанию Grid расширяет свои дочерние объекты, чтобы заполнить все свободное пространство в ячейке, так что это делает aborder2 растягиваться до 200 пикселей вместо 20.

Я думаю, что первый пример может быть аналогичной ситуацией, где Column2 является рендерингом на 0px, потому что у него нет контента, однако я не уверен, почему он устанавливает aborder2 на ширину 110. Кажется, что из 110 (GridWidth / TotalColumns) + (1stColumnWidth / TotalColumns * NumberOfStarColumns), поэтому я думаю, что это ошибка.

В качестве дополнительной заметки вы можете установить Column1 MaxWidth="20", чтобы заставить Column1 всегда отображаться как 20px

Ответ 2

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

Чтобы попытаться решить тайну того, откуда приходит 110, я предполагаю (200 - 20)/2 + 20

EDIT: Я пробовал несколько других формул, и это не задерживалось, больше похоже на:

(200 + 20)/2