2009-11-02 4 views
6

FrameworkElement을 직접 작성하고 VisualChildrenCount{get;}GetVisualChild(int index)을 내 DrawingVisual 인스턴스를 반환하여 덮어 씁니다.DrawingVisual이 새로 고쳐지지 않습니다.

DrawingVisual.RenderOpen()을 사용하여 초기 렌더링 (예 : 타이머 핸들러에서) 한 후 시각적 콘텐츠를 수정하면 요소가 새로 고쳐지지 않습니다.

using System; 
using System.Windows; 
using System.Windows.Media; 
using System.Windows.Threading; 

namespace VisualTest 
{ 
    public class TestControl : FrameworkElement 
    { 
     private readonly DrawingVisual _visual = new DrawingVisual(); 

     public TestControl() 
     { 
      Draw(false); 

      var timer = new DispatcherTimer {Interval = new TimeSpan(0, 0, 2)}; 
      timer.Tick += (sender, args) => 
           { 
            Draw(true); 
            InvalidateVisual(); 
            timer.Stop(); 
           }; 
      timer.Start(); 
     } 

     protected override Visual GetVisualChild(int index) 
     { 
      return _visual; 
     } 

     protected override int VisualChildrenCount 
     { 
      get { return 1; } 
     } 

     private void Draw(bool second) 
     { 
      DrawingContext ctx = _visual.RenderOpen(); 
      if (!second) 
       ctx.DrawRoundedRectangle(Brushes.Green, null, new Rect(0, 0, 200, 200), 20, 20); 
      else 
       ctx.DrawEllipse(Brushes.Red, null, new Point(100, 100), 100, 100); 
      ctx.Close(); 
     } 
    } 
} 

InvalidateVisual()는 아무것도하지 않습니다 :

다음은 간단한 예제입니다. 요소가 포함 된 창 크기를 조정하면 업데이트됩니다.

콘텐츠를 제대로 새로 고치는 방법에 대한 아이디어가 있으십니까? 바람직하게는 이없고은 내 요소에 대한 새 종속성 속성을 도입합니다.

답변

7

을 testControl 클래스 생성자에

this.AddVisualChild(_visual); 
this.AddLogicalChild(_visual); 

를 추가합니다.

+0

이 코드는 시각적으로 메모리에 누수가 발생하지만 트리에 추가 될 때 제거되지 않습니다. 더 나은 코드는 Loaded 이벤트에 시각적 요소를 추가하고 Unloaded 이벤트에서 제거하는 것입니다. 내 대답을 참조하십시오. – splintor

5

SMART_n's answer을 바탕으로, 여기에 누설하지 않는 향상된 솔루션입니다 메모리 :

public TestControl() 
    { 
     Loaded += AddVisualToTree; 
     Unloaded += RemoveVisualFromTree; 

     Draw(false); 

     var timer = new DispatcherTimer {Interval = new TimeSpan(0, 0, 2)}; 
     timer.Tick += (sender, args) => 
          { 
           Draw(true); 
           InvalidateVisual(); 
           timer.Stop(); 
          }; 
     timer.Start(); 

    } 

    private void AddVisualToTree(object sender, RoutedEventArgs e) 
    { 
     AddVisualChild(_visual); 
     AddLogicalChild(_visual); 
    } 

    private void RemoveVisualFromTree(object sender, RoutedEventArgs e) 
    { 
     RemoveLogicalChild(_visual); 
     RemoveVisualChild(_visual); 
    } 
0

당신이 _visualDrawingGroup을 할 경우-다시 열어 나중에하고 명령을 그리는 것 변경하고 그들이 의지 할 수 업데이트 되십시오.

관련 문제