【问题标题】:VerticalAlignment for ItemsPanelItemsPanel 的 VerticalAlignment
【发布时间】:2013-03-17 18:58:27
【问题描述】:

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

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

XAML:

a) 不起作用:使用 binding 时,该值已设置但仅在 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 发生之前没有通过绑定设置值?

提前致谢。

【问题讨论】:

  • 可能是因为DataBind runs before Render,并且在渲染父级之前未设置该值,因为通常WPF控件的默认大小调整样式基于父面板?您可能可以在您的 VerticalAlignment 绑定中放置一个转换器,并检查第一次评估时绑定的值是什么。
  • @Rachel 谢谢,在转换器之前到达了 ArrangeOverride 。答案是 2 。任何想法为什么它不首先继承该值是因为它们都是框架元素,哪个是另一个的子元素?
  • 如果您注释掉您的ArrangeOverride 方法,或者将base.ArrangeOverride() 添加到其中,该值是否会被继承?有可能默认值实际上是在 ArrangeOverride 方法中设置的,而您正在覆盖它。

标签: wpf vertical-alignment arrangeoverride


【解决方案1】:

FrameworkElement.VerticalAlignment 的默认值是Stretch,所以ReArrangeStackPanel.VerticalAlignment 类的默认值也是Stretch 是有道理的

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

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

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

    ...
}

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 2014-05-11
    • 1970-01-01
    • 2011-09-13
    • 2011-01-20
    相关资源
    最近更新 更多