2009-12-15 5 views
3

Silverlight에서 Canvas 클래스 (Reflector 포함)는 특별한 간단한 작업을 수행하지 않고 3 개의 종속 속성 (Left, Top, ZIndex)과 2 개의 MeasureOverride 및 ArrangeOverride 메서드를 매우 간단하게 구현합니다.Silverlight Canvas : 어떻게 작동합니까?

하지만 난처럼 내 구현을 사용하는 경우 :

class MyCanvas : Panel { /* Top and Left dependency properties implementation */ } 

그리고 표준 캔버스처럼 XAML에서 MyCanvas를 사용합니다. 예상대로 작동하지 않습니다 (빈 화면이 보입니다).

캔버스는 어떻게 구현 되었습니까?

- 추가 코드 : 표준 캔버스로 변경 MyCanvas, 난 위치 (10)에 충진 사각형을 볼 수있는 경우

<local:MyCanvas> 
    <Rectangle 
     local:MyCanvas.Left="10" 
     local:MyCanvas.Top="10" 
     Width="100" 
     Height="100" 
     Fill="Black" /> 
</local:MyCanvas> 

: 같은 XAML에서 사용 MyCanvas.cs

public class MyCanvas : Panel 
{ 
    public static double GetTop(DependencyObject obj) 
    { 
     return (double)obj.GetValue(TopProperty); 
    } 

    public static void SetTop(DependencyObject obj, double value) 
    { 
     obj.SetValue(TopProperty, value); 
    } 

    // Using a DependencyProperty as the backing store for Top. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty TopProperty = 
     DependencyProperty.RegisterAttached("Top", typeof(double), typeof(MyCanvas), new PropertyMetadata(0.0)); 


    public static double GetLeft(DependencyObject obj) 
    { 
     return (double)obj.GetValue(LeftProperty); 
    } 

    public static void SetLeft(DependencyObject obj, double value) 
    { 
     obj.SetValue(LeftProperty, value); 
    } 

    // Using a DependencyProperty as the backing store for Left. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty LeftProperty = 
     DependencyProperty.RegisterAttached("Left", typeof(double), typeof(MyCanvas), new PropertyMetadata(0.0)); 
} 

, 10.

<Canvas> 
    <Rectangle 
     Canvas.Left="10" 
     Canvas.Top="10" 
     Width="100" 
     Height="100" 
     Fill="Black" /> 
</Canvas> 
+0

Canvas 클래스 코드를 게시 할 수 있습니까? –

답변

2

이것은 Reflector의 Silverlight 분해 엔진의 버그 인 것 같습니다. 다음 단계로 자신의 실버 캔버스 컨트롤을 빌드 할 수 있습니다

  • 은 리플렉터에서 WPF 캔버스 제어를 분해 및 Visual Studio에 코드를 복사합니다.
  • DependencyPropertiesBottom 및 Right와 Get 및 Set 메서드를 제거합니다.
  • ArrangeOverride에서 Bottom 및 Right 절을 제거하십시오.
  • FrameworkPropertyMetadata를 PropertyMetadata로 바꿉니다.
  • DependencyProperty 초기화에서 속성 유효성 검사 인수를 제거하십시오.

이렇게 만든 캔버스에는 ZIndex 속성이 없습니다.

+2

그건 반사경 버그가 아니야. Silverlight 핵심 기능의 대부분은 원시 agcore.dll에서 구현되었습니다. 그리고 Canvas 구현은 자신의 구현 세부 사항을 "숨기기"위해 "핵심 종속성 속성"을 사용합니다 (DependencyProperty.RegisterCoreProperty 내부 메소드 참조). – Andir

+0

우수 튜토리얼, 감사합니다. 나는 MeasureOverride를 오버라이드 할 수있는 방법을 찾고 있었고 반사경 출력에서 ​​내 자신의 SL Canvas를 만들려고했다. –

0

Canvas는 말한대로 왼쪽 및 위쪽 속성이 추가 된 패널입니다. MSDN에 따르면

당신이 명시 적으로 지역에 상대적 좌표를 사용 으로 자식 개체를 배치 할 수있는 대상 영역을 정의합니다.

그게 전부입니다. 캔버스는 다른 FrameworkElement 파생 컨테이너 안에 명시 적 위치를 가질 수 있습니다. Handrolled Canvas가 표시되지 않으면 렌더링 오류가 발생할 수 있습니다. 배경색을 변경하여 보았는지 확인해 보셨습니까?

+0

그것의 렌더링 오류가 아니라 실버 라이트 구현의 일부 숨겨진 마법. 내 자신의 정렬 알고리즘을 구현하면 MyCanvas에서 자식 요소를 볼 수 있지만 실제 Canvas는 정렬 동작을 인식하지 못합니다. 몇 가지 의심스러운 세부 정보를 찾을 수 있습니다 : DependencyProperty.RegisterCoreProperty ([constant], typeof (double)); Left 및 Top 속성을 등록하려면 DependencyProperty.RegisterAttached를 사용하십시오. – Andir

0

내가 좋아하는 MeasureOverride 함수와 ArrangeOvverride 뭔가를 구현할 수 있습니다

protected override Size MeasureOverride(Size availableSize) 
    { 
     foreach (var element in Children) 
      element.Measure(availableSize); 
     return base.MeasureOverride(availableSize); 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
     foreach (var element in Children) 
     { 
      var left = GetLeft(element); 
      var top = GetTop(element); 
      var size = element.DesiredSize; 
      element.Arrange(
       new Rect(left, top, size.Width, size.Height) 
       ); 
     } 
     return base.ArrangeOverride(finalSize); 
    } 

을 그리고 MyCanvas 사용의 내 예에서 예상대로 나는 검은 색 사각형을 볼 수 있습니다.

하지만 캔버스는 이러한 방법을 구현하지 않습니다. 그것은 어떻게 작동합니까?!

관련 문제