0

iv'e 有一个从堆栈面板派生的自定义面板

这个面板有一个布局逻辑,它取决于面板的垂直对齐

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 属性继承自它是子项的项控件,似乎它没有,因为它设置为默认的“Stretch”值。

2)即使在 ItemsPanel 上显式设置 VerticalAlignment 时,如果我不硬编码,则在 ArrangeOverride 范围内将 VerticalAlignment 的值设置为“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 发生之前没有通过绑定设置值?

提前致谢 。

4

1 回答 1

0

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

由于 WPF 控件的典型大小调整样式通常基于父面板,因此ArrangeOverridea 的方法可能StackPanel是实际设置VerticalAlignmentStackPanel 属性的方法,而您正在覆盖该方法。

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

protected override Size ArrangeOverride(Size arrangeSize)
{
    base.ArrangeOverride(arrangeSize);

    ...
}

至于为什么绑定不起作用,我怀疑这是因为Rendering 发生在 DataBinding 之后,所以VerticalAlignment直到您绑定到的父控件被渲染之后才设置属性。

Converter您可以通过将 a放入您的VerticalAlignment绑定并检查它在评估时的值是什么来验证是否是这种情况。

于 2013-03-27T16:28:45.070 回答