Вертикальное выравнивание для 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 связывание и проверка значения, когда оно оценивается.

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