[英]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。
MeasureOverride和ArrangeOverride
實際上,您的度量邏輯可能與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.