ItemsPanel的VerticalAlignment

时间:2013-03-27 15:50:26

标签: wpf vertical-alignment arrangeoverride

我有一个自定义面板,它来自堆栈面板

此面板的布局逻辑取决于面板的垂直对齐

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)我希望ItemsPanel的VerticalAligment属性是继承的 项目控制它是一个孩子,它似乎没有,因为它是默认设置 “拉伸”价值。

2)即使在ItemsPanel上明确设置VerticalAlignment,如果我不对该值进行硬编码    VerticalAlignment在ArrangeOverride范围内设置为“Stretch”,并且仅在稍后(我使用snoop观察)设置为“Bottom”值。

XAML:

a)不起作用:使用绑定,设置值但仅在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>

b)有效:对值进行明确的硬编码。

    <ItemsPanelTemplate>
         <local:ReArrangeStackPanel VerticalAlignment="Bottom" />
    </ItemsPanelTemplate>

在我的Windows XAML中,ItemsControl(PipeControl)设置了所需的VerticalAlignment。

所以我的问题:

1)为什么价值不被继承?

2)为什么在ArrangeOverride发生之前没有通过绑定设置值?

提前谢谢。

1 个答案:

答案 0 :(得分:0)

FrameworkElement.VerticalAlignment的默认值为Stretch,因此ReArrangeStackPanel.VerticalAlignment类的默认值也是Stretch

由于WPF控件的典型调整样式通常基于父面板,因此ArrangeOverride的{​​{1}}方法可能实际上为StackPanel属性设置了StackPanel,你正在覆盖那个方法。

如果确实如此,那么您可以通过在VerticalAlignment方法中调用base.ArrangeOverride()来确保正确设置默认值

ArrangeOverride()

至于为什么绑定不起作用,我怀疑它是因为Rendering occurs after DataBinding,所以protected override Size ArrangeOverride(Size arrangeSize) { base.ArrangeOverride(arrangeSize); ... } 属性直到你绑定的父控件被渲染之后才被设置。

您可以通过在VerticalAlignment绑定中放置Converter并查看评估时的值来验证是否是这种情况。