캔버스 컨트롤을 작성 중입니다. 이 루트 캔버스에는 여러 개의 겹치는 하위 항목 (캔버스)이 있습니다. 이것은 각 어린이가 자신의 그림을 다룰 수 있도록하기 위해 수행되며 원하는 동작을 얻기 위해 자녀의 조합으로 최종 결과를 작성할 수 있습니다.wpf wpf 컨트롤이 겹쳐서 마우스 이벤트를받지 못했습니다.
이것은 렌더링과 관련하여 매우 잘 작동합니다. 그러나 마우스 이벤트에서는 잘 작동하지 않습니다. 방법 마우스 이벤트 작품 (예를 들어 previewmousemove 사용) 다음과 같습니다 : 하나의 마우스, 화재 이벤트 중에 있으며
을 중지하면 루트 캔버스, 마우스, 화재 이벤트 2 체크 모든 어린이 아래1 경우
이와 같이, 내가 추가 한 첫 번째 자식 만 마우스 이동 이벤트를 수신합니다. 이벤트는 겹치기 때문에 모든 하위 항목에 전달되지 않습니다.
는이 문제를 극복하기 위해, 나는 다음과 같은 시도 : 모든 어린이를위한 VisualTreeHelper.HitTest 3를 사용하여 이벤트를 처리 할 모든 아이들을 찾아, 루트 캔버스 모든 이벤트에 대한 2에서 1 무시 마우스 이벤트를이 유효한 히트 테스트 결과를 반환했습니다 (예 : 마우스 아래에서 이벤트를 처리하고자하는 경우 (IsHitTestVisible == true))?
이것은 내가 붙어있는 곳입니다. 어떻게 든 마우스 이벤트를 모든 자식에게 보내고 첫 번째 자식이 두 번받지 못하도록 이벤트의 일반적인 흐름을 중지해야합니다. 행사).
동일한 이벤트가 전달 된 RaiseEvent를 사용하면 모든 것이 작동하는 것처럼 보이지만 어쨌든 부모 (루트 캔버스)에서도 이벤트가 발생합니다. 이것을 우회하려면 이벤트 복사본을 만들고 강제 설정을 통해 소스를 설정해야했지만 솔루션보다 해킹 된 것으로 보입니다. 내가하려는 일을하는 적절한 방법이 있습니까? 코드 예는 다음과 같습니다.
public class CustomCanvas : Canvas
{
private List<object> m_HitTestResults = new List<object>();
public new event MouseEventHandler MouseMove;
public CustomCanvas()
{
base.PreviewMouseMove += new MouseEventHandler(CustomCanvas_MouseMove);
}
private void CustomCanvas_MouseMove(object sender, MouseEventArgs e)
{
// Hack here, why is the event raised on the parent as well???
if (e.OriginalSource == this)
{
return;
}
Point pt = e.GetPosition((UIElement)sender);
m_HitTestResults.Clear();
VisualTreeHelper.HitTest(this,
new HitTestFilterCallback(OnHitTest),
new HitTestResultCallback(OnHitTest),
new PointHitTestParameters(pt));
MouseEventArgs tmpe = new MouseEventArgs(e.MouseDevice, e.Timestamp, e.StylusDevice);
tmpe.RoutedEvent = e.RoutedEvent;
tmpe.Source = this;
foreach (object hit in m_HitTestResults)
{
UIElement element = hit as UIElement;
if (element != null)
{
// This somehow raises the event on us as well as the element here, why???
element.RaiseEvent(tmpe);
}
}
var handlers = MouseMove;
if (handlers != null)
{
handlers(sender, e);
}
e.Handled = true;
}
private HitTestFilterBehavior OnHitTest(DependencyObject o)
{
UIElement element = o as UIElement;
if (element == this)
{
return HitTestFilterBehavior.ContinueSkipSelf;
}
else if (element != null && element.IsHitTestVisible && element != this)
{
return HitTestFilterBehavior.Continue;
}
return HitTestFilterBehavior.ContinueSkipSelfAndChildren;
}
private HitTestResultBehavior OnHitTest(HitTestResult result)
{
// Add the hit test result to the list that will be processed after the enumeration.
m_HitTestResults.Add(result.VisualHit);
// Set the behavior to return visuals at all z-order levels.
return HitTestResultBehavior.Continue;
}
루트 캔버스 하위의 하위에있는 툴팁을 사용하려면이 기능이 필요합니다. –
실버 라이트 용입니까? WPF? 관련 태그를 추가하면 더 빨리 답변을 얻을 수 있습니다. – SirDemon