Вертикальное выравнивание для ItemsPanel
У меня есть пользовательская панель, которая происходит от панели стека
эта панель имеет логику компоновки, которая зависит от вертикального выравнивания панели
CS:
public class ReArrangeStackPanel : StackPanel
{
protected override Size ArrangeOverride(Size arrangeSize)
{
double delta = this.VerticalAlignment == System.Windows.VerticalAlignment.Bottom
? CalcForBottom() : CalcForTop();
ChildrenArrangement(delta);
return base.ArrangeOverride(arrangeSize);
}
1) я бы ожидал, что свойство VerticalAligment ItemsPanel будет унаследовано от элемента управления items, дочерним элементом которого он является, похоже, что нет, поскольку для него установлено значение по умолчанию "Stretch".
2) Даже при явной установке VerticalAlignment на ItemsPanel, если я не кодирую жестко, значение VerticalAlignment устанавливается в "Stretch" в области ArrangeOverride, и только позже (что я наблюдаю с помощью snoop) устанавливается с "Bottom" значение.
XAML:
а) не работает: с привязкой значение устанавливается, но только после ArrangeOverride.
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<local:ReArrangeStackPanel
VerticalAlignment="{Binding Path=VerticalAlignment,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:PipeControl}}}" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
б) работает: явно жесткое кодирование значения.
<ItemsPanelTemplate>
<local:ReArrangeStackPanel VerticalAlignment="Bottom" />
</ItemsPanelTemplate>
в моем Windows XAML ItemsControl (PipeControl) установлен с требуемым VerticalAlignment .
Итак, мои вопросы:
1) почему значение не наследуется?
2) почему значение не устанавливается через привязку до появления ArrangeOverride?
заранее спасибо.
1 ответ
Значением по умолчанию FrameworkElement.VerticalAlignment является Stretch
, так что имеет смысл, что значение по умолчанию для вашего ReArrangeStackPanel.VerticalAlignment
класс также Stretch
Поскольку типичный стиль определения размеров для элементов управления WPF обычно основан на родительской панели, возможно, что ArrangeOverride
метод StackPanel
это то, что на самом деле устанавливает VerticalAlignment
свойство для StackPanel, и вы перезаписываете этот метод.
Если это действительно так, то вы можете убедиться, что значение по умолчанию установлено правильно, вызвав base.ArrangeOverride()
в вашем ArrangeOverride()
метод
protected override Size ArrangeOverride(Size arrangeSize)
{
base.ArrangeOverride(arrangeSize);
...
}
Что касается того, почему привязка не работает, я подозреваю, что это происходит потому, что рендеринг происходит после DataBinding, поэтому VerticalAlignment
свойство не устанавливается до тех пор, пока не будет отображен родительский элемент управления, с которым вы связываетесь.
Вы можете проверить, если это так или нет, поставив Converter
в вашем VerticalAlignment
связывание и проверка значения, когда оно оценивается.