캔버스의 Mouseleftbuttondown에는 너무 많은 정밀도가 필요합니다
문제
WPF 캔버스에 추가 된 요소에 대한 Mouseleftbuttondown 이벤트에 응답하고 있습니다. 클릭하면 모두 잘 작동하지만 (예 : EventHandler가 올바르게 발사됩니다) 마우스 포인터에서 너무 많은 정밀도가 필요합니다. 당신은 그것을 작동 시키려면 원의 꼭대기에 있어야합니다. 조금 더 용서해야합니다. 어쩌면 최소한 1 ~ 2 개의 픽일을 용서할 수 있습니다. 캔버스의 요소는 멋진 큰 원 (화면의 1/4 크기)이므로 원 자체는 너무 작지 않지만 각각의 뇌졸중은 1이므로 얇은 선입니다.
여기에서 스크린 샷을 볼 수 있습니다. http://twitpic.com/1f2ci/full
대부분의 그래픽 앱은 마우스 선택에 대해 까다 롭지 않으므로 사용자에게 친숙한 경험을 제공하고 싶습니다.
어떻게 조금 더 용서할 수 있습니까?
해결책
루트 레이아웃 객체의 MouseleftButtondown 이벤트에 연결하고이를 수행하여 클릭 한 범위에 어떤 요소가 있는지 확인할 수 있습니다.
List<UIElement> hits = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(Point, yourLayoutRootElement) as List<UIElement>;
http://msdn.microsoft.com/en-us/library/cc838402(vs.95).aspx
포인트 매개 변수의 경우 MouseeventArgs 매개 변수 e를 사용하고 다음과 같은 GetPosition 메소드를 호출 할 수 있습니다.
Point p = e.GetPosition(null)
FindElementsInhostCoordinates 대신 hittest를 사용하는지 여부를 기억할 수 없습니다. 둘 다 시도하십시오.
http://msdn.microsoft.com/en-us/library/ms608752.aspx
마우스 위치에서 4 개의 포인트 객체를 생성하여 가짜 공차 효과를 생성하고 4 점 모두에 대해 FindElementsInmentsInhostCoordinates 또는 HitTest를 호출 할 수 있습니다.
다른 팁
투명한 색상으로 원을 채우려면 전체 원을 클릭 할 수있게하려고 할 수도 있습니다.
실패하면 다른 원과 같은 위치에 도우미 원을 그릴 수도 있습니다. 원 전경 색상을 투명하게 만들고 브러시의 두께 몇 픽셀을 원 주위에 더 허용 가능한 클릭 가능한 영역을 위해 몇 픽셀을 더 넓게 만드십시오 ..
도움이 되었기를 바랍니다!
나는 내가 그것을했다고 생각한다 (당신이 나를 시작하는 데 도움이된다) ...
먼저, 이동 이벤트 처리를 각 타원 대신 캔버스로 옮겼습니다. 그것은 OOP 관점에서 좋고 나쁘다. 적어도 마우스 이벤트 처리가 Holepattern의 책임 일 때 각 구멍 (구멍의 시각적 타원)에 설정해야 할 경우, 내 Holepattern의 모든 소비자 가이 기능을 자동으로 얻을 수 있도록 추상화됩니다. 그러나 메인 UI 코드로 이동함으로써 이제는 캔버스 마우스 이벤트를 더 높은 수준으로 다루고 있습니다. 그러나 그것은 모두 나쁘지는 않습니다. 우리는이 부분을 며칠 동안 논의 할 수 있습니다.
요점은 마우스로 캔버스에서 무언가를 골라 내고 선택한 타원이 속한 구멍을 읽을 때 "오류의 여백"을 만들 수있는 방법을 설계 한 다음 구멍이 속한 Holepattern을 읽을 수 있습니다. 그리고 내 전체 UI (ListView, TextBoxes, GridView FO 좌표)는 모두 기존 XAML 바인딩으로 업데이트되며 캔버스는 기존 메소드로 한 번의 호출로 업데이트되어 캔버스를 재생합니다.
솔직히 말해서, 나는이 모든 것을 알아 냈다고 믿을 수 없다 (물론 당신의 도움과 다른 사람들도). 이것의 비전을 가지고 있고 그것이 오는 것을 본 것은 정말 멋진 느낌입니다.
여기에서 기본 코드를 확인하십시오.
void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
int ClickMargin = 2;
Point ClickedPoint = e.GetPosition(canvas1);
Point p1 = new Point(ClickedPoint.X - ClickMargin, ClickedPoint.Y - ClickMargin);
Point p2 = new Point(ClickedPoint.X - ClickMargin, ClickedPoint.Y + ClickMargin);
Point p3 = new Point(ClickedPoint.X + ClickMargin, ClickedPoint.Y + ClickMargin);
Point p4 = new Point(ClickedPoint.X + ClickMargin, ClickedPoint.Y - ClickMargin);
var PointPickList = new Collection<Point>();
PointPickList.Add(ClickedPoint);
PointPickList.Add(p1);
PointPickList.Add(p2);
PointPickList.Add(p3);
PointPickList.Add(p4);
foreach (Point p in PointPickList)
{
HitTestResult SelectedCanvasItem = System.Windows.Media.VisualTreeHelper.HitTest(canvas1, p);
if (SelectedCanvasItem.VisualHit.GetType() == typeof(Ellipse))
{
var SelectedEllipseTag = SelectedCanvasItem.VisualHit.GetValue(Ellipse.TagProperty);
if (SelectedEllipseTag!=null && SelectedEllipseTag.GetType().BaseType == typeof(Hole))
{
Hole SelectedHole = (Hole)SelectedEllipseTag;
SetActivePattern(SelectedHole.ParentPattern);
SelectedHole.ParentPattern.CurrentHole = SelectedHole;
}
}
}
}
타원의 스트로크 두께를 늘려 조절할 수 있도록
따라서 Mouseleftbuttondown 이벤트 작품 예제 : elipse 태그 :
타원 Canvas.left = "10"canvas.top = "133"height = "24"name = "elipse1"width = "23"stroke = "red"mouseleftbuttondown = "elipse1_mouseleftbutttondown"툴팁 = "strokendlinecap ="flat " Strokethickness = "12"
개인 void ellipse1_mouseleftbuttondown (객체 발신자, MouseButtoneventArgs e) {application curapp = application.current; curapp.shutdown (); }