2012-10-23 3 views
0

WPF에서 컨트롤의 왼쪽 위 모서리가 아닌 것을 기준으로 DrawingContext과 관련된 내용을 그리는 방법을 궁금해 왔습니다. 내 문제는 다양한 도트를 연결하여 도형을 그려야한다는 것입니다.이 도트는 호스트 컨트롤의 중심을 기준으로 위치를 지정해야하며 Y는 위쪽을 향하게해야합니다.DrawingContext를 사용하여 중심을 기준으로 그리기

내 요소는 사용자 정의 DrawingVisual 하위 클래스의 트리를 사용하여 렌더링되며 루트는 Border 하위 클래스는 VisualCollection입니다. 나는 이 BorderScaleTransform을 지정하여 Y 방향 문제를 해결했으며, 기본적으로 전체 컨트롤을 수직으로 뒤집었다.

그래도 다른 문제는 없습니다. 내 기원을 집중시키는 방법에 대한 아이디어가 있습니까?

답변

0

좋아, 알았다. 내가 해낸 방법은 다음과 같습니다.

먼저 GroupTransform을 정의하고 Border 하위 클래스의 속성에 할당되었습니다. 나는 내 사용자 지정 DrawingVisual의 새 인스턴스를 만들 때

var trans = new TranslateTransform(); 
var conv = new HalfConverter(); // a custom converter that halves whatever you pass to it 
BindingOperations.SetBinding(trans, TranslateTransform.XProperty, new Binding { Path = new PropertyPath(ActualWidthProperty), Source = this, Converter = conv }); 
BindingOperations.SetBinding(trans, TranslateTransform.YProperty, new Binding { Path = new PropertyPath(ActualHeightProperty), Source = this, Converter = conv }); 

WorldTransform = new TransformGroup(); 
WorldTransform.Children.Add(new ScaleTransform { ScaleY = -1.0 }); 
WorldTransform.Children.Add(trans); 
VisualTransform = WorldTransform; 

그런 다음, 내 WorldTransform에 그 Transform 속성을 할당합니다.

// ZoneVisual is my DrawingVisual subclass 
var vis = new ZoneVisual(zone) { Transform = WorldTransform }; 

내가 (그런데하는 Node) 새로운 요소를 추가

, 나는 단순히 내 WorldTransform의 역하여 변환해야합니다.

Voila. 이것은 최선의 방법은 아니지만 꽤 잘 작동하는 것 같습니다. 나는 현저하게 높은 성능을 필요로하지 않기 때문에 아마 그 일을 할 것입니다.

1

ScaleTransform 대신 y 방향으로 -1만큼 크기가 조정 된 MatrixTransform을 사용할 수 있으며 좌표 원점을 컨트롤의 가운데로 변환합니다. 그러나이 변형은 컨트롤의 크기가 변경 될 때마다 업데이트되어야합니다. 따라서 당신이 (당신이 컨트롤의 RenderTransform 속성을 설정한다고 가정)처럼 아래 OnRenderSizeChanged 무시할 것 :

protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) 
{ 
    base.OnRenderSizeChanged(sizeInfo); 

    RenderTransform = new MatrixTransform(1d, 0d, 0d, -1d, 
     sizeInfo.NewSize.Width/2d, sizeInfo.NewSize.Height/2d); 
} 

편집 : 당신이 전체 컨트롤을 변환하고 싶지 않은 경우, 당신은 또한 클래스로 MatrixTransform을 정의 할 수 있습니다 시각적 인 하위 컬렉션의 모든 비주얼에 적용합니다. 크기에

ContainerVisual visual = ... 
visual.Transform = transform; 

당신이 단순히 MatrixTransform을 업데이트 변경 : 모든 새로운 시각의 변환 속성을

private MatrixTransform transform = new MatrixTransform(); 

지정은 변환

물론
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) 
{ 
    base.OnRenderSizeChanged(sizeInfo); 

    transform.Matrix = new Matrix(1d, 0d, 0d, -1d, 
     sizeInfo.NewSize.Width/2d, sizeInfo.NewSize.Height/2d); 
} 

에만 적용해야 "최상위 레벨"비주얼. 그 비주얼의 아이들은 부모의 변형에 의해 변형 될 것입니다. "VisualCollection이 포함 된 테두리 하위 클래스"로 시각을 관리하는 방법을 정확히 이해하지 못합니다. 일반적인 접근법은 부모 ContainerVisual을 시각적 트리의 루트로 갖는 것입니다. 그런 다음 변환은이 루트 시각에만 적용됩니다.

+0

이것은 불행히도 전체'Border' 컨트롤을 움직입니다. –

+0

내 편집을 참조하십시오. 나는 아직도 당신의 솔루션보다 훨씬 간단하다고 생각합니다. 요점은 모든 Visual에 대해 동일한 Transform 인스턴스를 사용한다는 것입니다. – Clemens

+0

그건 내 솔루션이하는 일입니다. –