길버트님의 "[엉뚱한실험4] Transform이 적용된 객체에서 MouseEventArgs GetPosition 결과값 비교"를 보다가 문득 더 궁금해진 것이 있어서 추가로 테스트 해봤어요.

테스트 결과는 RenderTransform이 적용된 개체의 GetPosition(자기자신)의 위치는 어떤 변형이 있더라도 원래 자신의 위치에 대한 상대적인 값이 나온다...였는데요, 그렇다면 GetPosition(부모) 또는 실버라이트 영역 전체에 대한 위치를 얻는 GetPosition(Null)을 하면 어떻게 될까요?

네, 결과는 당연하게도 자기 자신을 대상으로 한 GetPosition은 자신의 원래 영역에 관련된 값이 나오지만 GetPosition에 다른 개체를 넣으면 해당 개체로부터 이벤트가 발생된 지점까지의 절대적인 위치가 나오네요. 참고로 갈색 Rectangle이 테스트 대상이고 Cyan(밝은 하늘색) 테두리는 Rectangle을 포함하고 있는 부모 Canvas의 위치를 나타내고 있어요.

각 부모 Canvas의 좌표는 위에서부터,
None : (50, 50)
ScaleTransform : (50, 150)
RotateTransform : (50, 250)
TranslateTransform : (50, 350)
SkewTransform : (50, 450)
이고 위의 스크린샷에서 마우스의 위치는 각각 Rectangle의 오른쪽 아래 모서리를 기준으로 했어요.

그래서 이 테스트가 말하고 있는게 뭐냐고요? 별거 없어요. RenderTransform을 먹인 개체에 대한 MouseEventArgs.GetPosition을 사용할 때 주의하라는 거죠.

흔히 어떤 개체를 드래그&드랍할 때 MouseMove 이벤트에서 마우스가 이동된 좌표를 얻기 위해 e.GetPosition(sender as UIElement)라고 쓸 수 있는데요, 만약 이렇게 했을 때 개체에 RenderTransform가 적용되어 있다면 원치 않은 결과를 얻을 수 있겠죠. 드래그&드랍이나 클릭된 지점에 어떤 효과를 줄 때에는 가급적 e.GetPosition(null)을 사용하여 절대적인 경로를 기준으로 하는 것이 좋을거에요.

반대로, 어떤 Canvas에 RenderTransform이 적용되어 있고 그 Canvas 내부에서만 움직이거나 표현되는 개체에 대한 상대적인 좌표 계산은 e.GetPosition(해당 Canvas)로 하는 것이 적절하겠죠.

테스트는 다음 링크에서 해볼 수 있고 프로젝트 파일도 첨부했으니 관심 있으신 분은 받아서 해보시길.
테스트 : http://gongdo.oranc.co.kr/Silverlight/Samples/TransformTest2/TestPage.html
다운로드 :

신고
Posted by gongdo


티스토리 툴바