上書きすることができます。
すぐに取得できるのは、コントロールに論理親が1つしかないという例外です。
あなたができることは二重委譲を行うことですが。あなたのパネルの代議員は別のパネルに測定/アレンジを行い、その代わりにそれに子どもの役目を果たす「幽霊」を提供し、パネルの子供たちに自分の測定/アレンジを委任します。
は、ここでは、コードです:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
public class DelegatePanel : Panel
{
private sealed class DelegateChild : FrameworkElement
{
readonly Func<Size, Size> measure;
readonly Func<Size, Size> arrange;
public DelegateChild(Func<Size,Size> measure, Func<Size,Size> arrange)
{
this.measure = measure;
this.arrange = arrange;
}
protected override Size MeasureOverride(Size availableSize)
{
return measure(availableSize);
}
protected override Size ArrangeOverride(Size finalSize)
{
return arrange(finalSize);
}
}
readonly Dictionary<UIElement, UIElement> delegateByChild = new Dictionary<UIElement,UIElement>();
public Panel LayoutPanel
{
get { return (Panel)GetValue(LayoutPanelProperty); }
set { SetValue(LayoutPanelProperty, value); }
}
public static readonly DependencyProperty LayoutPanelProperty =
DependencyProperty.Register("LayoutPanel", typeof(Panel), typeof(DelegatePanel), new PropertyMetadata(null));
protected override Size MeasureOverride(Size availableSize)
{
if(this.LayoutPanel==null)
return base.MeasureOverride(availableSize);
this.delegateByChild.Clear();
this.LayoutPanel.Children.Clear();
foreach (UIElement _child in this.Children)
{
var child = _child;
var delegateChild = new DelegateChild(
availableChildSize =>
{
child.Measure(availableChildSize);
return child.DesiredSize;
},
finalChildSize =>
{
return finalChildSize;
});
delegateByChild[child] = delegateChild;
this.LayoutPanel.Children.Add(delegateChild);
}
this.LayoutPanel.Measure(availableSize);
return this.LayoutPanel.DesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
if(this.LayoutPanel==null)
return base.ArrangeOverride(finalSize);
this.LayoutPanel.Arrange(new Rect(finalSize));
foreach (var kv in delegateByChild)
{
var child = kv.Key;
var delegateChild = kv.Value;
var position = delegateChild.TranslatePoint(default(Point), this.LayoutPanel);
Rect finalChildBounds = new Rect(
position,
delegateChild.RenderSize);
child.Arrange(finalChildBounds);
}
return this.LayoutPanel.RenderSize;
}
}
免責事項:これはVirtualizingPanelを実装していません。だからItemsControlとギャングの内部で動作しますが、大規模なコレクションには十分速く動作しません。
「どのパネル」でもどんなアニメーションができると思いますか?パネルのさまざまなタイプ(グリッド、キャンバス、スタックパネル、ドックパネルなど)は、アイテムの配置方法がまったく異なっています。私はあなたが何を記述するための一般的な方法があるかわかりません... –
あります。しかし、それは私の知っている方法であり、それを記述することは容易ではありません。しかし、技術的な詳細は私には問題があるようです:( – drasto