2009-02-24 27 views
6

私は.NET 3.5でAdornerを使用しています。私はOnRenderをオーバーライドして描画することができますが、外観を変更するにはアドルナーを再描画する必要があります。adorner内のアニメーション(OnRender呼び出し)

私は描画コンテキストをクリアしてOnRenderを再度呼び出す方法を探しています。これを行うための最善の方法は何ですか、より良いアプローチがありますか?

public class MyAdorner : Adorner 
{ 
    private Brush brush = Brushes.Red; 

    public DragArrowAdorner(UIElement adornedElement) : base(adornedElement) 
    {} 

    public void RedrawWithBrush(Brush newBrush) 
    { 
     brush = newBrush; 

     // redraw..? 
    } 

    protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) 
    { 
     // some drawing code... 
     drawingContext.DrawRectangle(
      brush, 
      null, 
      new Rect(AdornedElement.DesiredSize)); 
    } 
} 

答えて

10

あなたの質問への答えは、しかし、私が代わりにカスタムに標準スタイルとビジュアルツリーのテンプレートを使用するために自分自身OnRenderに描くことの示唆しOnRenderが

再び呼ばれるように引き起こすことがInvalidateVisualを使用していますアドナーの実際のビジュアルを構築する。これは、ストーリーボードを使用して標準のXAMLアニメーションをその内部で実行できることも意味します。

あなたがこのアプローチに行きたい場合は、あなたのadornerクラスで必要に:コンストラクタで

  • base.AddVisualChild()を呼び出すか、あなたはadornerに表示するビジュアルを使用して独自のビジュアルコレクションを作成するのいずれか
  • ArrangeOverride(Size size)をオーバーライドして、適切に子供を配置します。
  • VisualChildrenCountをオーバーライドすると、adornerビジュアルツリーの子の数が返されます。
  • GetCisualChild(int index)を指定すると、特定の子を返すことができます。

詳細については、ResizingAdorner MSDNサンプルをご覧ください。

0

WPFはWindows.Formsと似ていないことを理解することが非常に重要です。 OnRender()は実際にはAccumulateDrawingObjects()と呼ばれるはずです。 WPFには、必要なときにいつでもUIを描画できるように保持されている一連の描画オブジェクトが蓄積されます。効率的にUIを更新するという魔法は、OnRender()の後に、そのビジュアルツリーのオブジェクトをに変更できることです。

たとえば、DrawingGroupを「backingStore」にしてOnRenderの間にDrawingContextに入れることができます。その後、いつでもビジュアルを変更したい場合は、DrawingGroup.Open()に新しい描画コマンドを入れ、WPFがUIのその部分を効率的に再描画します。

それは次のようになります。

DrawingGroup backingStore = new DrawingGroup(); 

protected override void OnRender(DrawingContext drawingContext) {  
    base.OnRender(drawingContext);    

    Render(); // put content into our backingStore 
    drawingContext.DrawDrawing(backingStore); 
} 

// I can call this anytime, and it'll update my visual drawing 
// without ever triggering layout or OnRender() 
private void Render() {    
    var drawingContext = backingStore.Open(); 
    Render(drawingContext); 
    drawingContext.Close();    
} 
関連する問題