在WPF构建可逆的StackPanelWPF、StackPanel

2023-09-03 07:39:37 作者:Ψ{掛帥绌征

我想建立一个自定义的的StackPanel ReverseOrder 属性,我可以声明设置为true,有在StackPanel中的元素出现在正常(例如,底部到顶部或从右到左)的相反顺序。它需要是可逆的飞行。

I'd like to build a custom StackPanel with a ReverseOrder property that I can declaratively set to true to have the elements in the StackPanel appear in the opposite order of normal (e.g. bottom to top or right to left). It needs to be reversible on the fly.

我想得出的StackPanel的一类新的,但我需要知道什么方法来覆盖。

I'm thinking of deriving a new class from StackPanel, but I need to know what methods to override.

最终的解决方案:

protected override System.Windows.Size ArrangeOverride( System.Windows.Size arrangeSize ) {
    double x = 0;
    double y = 0;

    IEnumerable<UIElement> children = ReverseOrder ? InternalChildren.Cast<UIElement>().Reverse<UIElement>() : InternalChildren.Cast<UIElement>();
    foreach ( UIElement child in children ) {
        var size = child.DesiredSize;
        child.Arrange( new Rect( new Point( x, y ), size ) );

        if ( Orientation == Orientation.Horizontal )
            x += size.Width;
        else
            y += size.Height;
    }

    if ( Orientation == Orientation.Horizontal )
        return new Size( x, arrangeSize.Height );
    else
        return new Size( arrangeSize.Width, y );
}

此外定义和注册 ReverseOrder 和呼叫 UpdateLayout请,如果它的变化。

Also define and register ReverseOrder and call UpdateLayout if it changes.

推荐答案

您可以重新实现FrameworkElement.ArrangeOverride并以相反的顺序比平时调用所有的child.Arrange必要时。

You can reimplement FrameworkElement.ArrangeOverride and invoke all the child.Arrange in the reverse order than usual when necessary.

http://msdn.microsoft.com/en-us/library/system.windows.uielement.arrange.aspx

事情是这样的(未测试):

Something like this (not tested):

    double x = 0;
    double y = 0;

    var children = ReverseOrder ? InternalChildren.Reverse() : InternalChildren;
    foreach (UIElement child in children)
    {
        var size = child.DesiredSize;
        child.Arrange(new Rect(new Point(x, y), size));

        if (Orientation == Horizontal)
            x += size.Width;
        else
            y += size.Height;
    }

请确保你改变ReverseOrder属性后,调用UpdateLayout请。

Make sure you invoke UpdateLayout after changing ReverseOrder property.