簡體   English   中英

在WPF中構建可逆的StackPanel

[英]Building a reversible StackPanel in WPF

我想構建一個帶有ReverseOrder屬性的自定義StackPanel ,我可以聲明性地將其設置為true,以使StackPanel中的元素以正常的相反順序出現(例如從下到上或從右到左)。 它需要在運行中可逆。

我正在考慮從StackPanel派生一個新類,但我需要知道要覆蓋哪些方法。

最終解決方案

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

您可以重新實現FrameworkElement.ArrangeOverride並在必要時以相反的順序調用所有child.Arrange。

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

像這樣的東西(未經測試):

    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。

MeasureOverrideArrangeOverride

實際上,您的度量邏輯可能與StackPanel相同,因此您可能只能覆蓋ArrangeOverride。 請注意,StackPanel有一些處理滾動的邏輯,如果您自己編寫,可能需要復制。 您可能希望直接從Panel繼承而不嘗試支持滾動。

請參閱面板上的MSDN頁面中的自定義面板元素或編寫自定義面板的各種博客條目,例如WPF教程 - 創建自定義面板控件在WPF中創建自定義面板

這是另一種變體。 它基於StackPanel參考源 ,並且能夠處理項目對齊。

public class ReversibleStackPanel : StackPanel
{
    public bool ReverseOrder
    {
        get => (bool)GetValue(ReverseOrderProperty);
        set => SetValue(ReverseOrderProperty, value);
    }

    public static readonly DependencyProperty ReverseOrderProperty =
        DependencyProperty.Register(nameof(ReverseOrder), typeof(bool), typeof(ReversibleStackPanel), new PropertyMetadata(false));


    protected override Size ArrangeOverride(Size arrangeSize)
    {
        bool fHorizontal = (Orientation == Orientation.Horizontal);
        var  rcChild = new Rect(arrangeSize);
        double previousChildSize = 0.0;

        var children = ReverseOrder ? InternalChildren.Cast<UIElement>().Reverse() : InternalChildren.Cast<UIElement>();
        foreach (UIElement child in children)
        {
            if (child == null)
                continue;

            if (fHorizontal)
            {
                rcChild.X += previousChildSize;
                previousChildSize = child.DesiredSize.Width;
                rcChild.Width = previousChildSize;
                rcChild.Height = Math.Max(arrangeSize.Height, child.DesiredSize.Height);
            }
            else
            {
                rcChild.Y += previousChildSize;
                previousChildSize = child.DesiredSize.Height;
                rcChild.Height = previousChildSize;
                rcChild.Width = Math.Max(arrangeSize.Width, child.DesiredSize.Width);
            }

            child.Arrange(rcChild);
        }

        return arrangeSize;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM