2011-01-19 7 views
1

デコレータpaternを使用するカスタムPanelを書きたいと思います。つまり、それはプロパティとして別のPanelを持つことを意味します。私のカスタムパネルにいくつかの要素が追加されたときに、(プロパティに格納されている)飾りパネルにも追加したいところがあり、いくつかの要素が削除されたら、それを飾りパネルからも削除したいと思います。それ、どうやったら出来るの ?WPF Panelを飾る方法は?

InternalCholdrensへの変更が発生したときに、オーバーライドする方法や、何らかのイベントが発生することはありますか? Basiclyは私がアニメーションの一つに任意のパネルを有効にするthisのような何かをしたい:

はあなたに

EDITありがとうございます。だから私はデコレータでパネルを飾りたいので、アニメーションになります。

+0

「どのパネル」でもどんなアニメーションができると思いますか?パネルのさまざまなタイプ(グリッド、キャンバス、スタックパネル、ドックパネルなど)は、アイテムの配置方法がまったく異なっています。私はあなたが何を記述するための一般的な方法があるかわかりません... –

+0

あります。しかし、それは私の知っている方法であり、それを記述することは容易ではありません。しかし、技術的な詳細は私には問題があるようです:( – drasto

答えて

1

私は完全にこの質問のコンテキストを理解していないが、あなたはあなたが、残念ながら、それを行うことはできませんOnVisualChildrenChanged

http://msdn.microsoft.com/en-us/library/system.windows.controls.panel.onvisualchildrenchanged.aspx

+0

同じ方法を考えていましたが、正しい練習ですか?バインディングのために要素が追加されたときにOnVisualChildrenChangedも呼び出されますか?ボーダーが追加されたときにOnVisualChildrenChangedが変更されましたか?それは望ましくない... – drasto

2

上書きすることができます。

すぐに取得できるのは、コントロールに論理親が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とギャングの内部で動作しますが、大規模なコレクションには十分速く動作しません。

+0

最初に "二重委譲"を見たとき、あなたが言ったと確信していました*あなたができることは[Double Dragon] //en.wikipedia.org/wiki/Double_Dragon)**完全に同意します:) –

+0

しかし、DockPanel.Dockのようなものは、委任されたレイアウトパネルのために実際の子供からゴーストの子供に伝播することはありません。 –

関連する問題