События в WPF: Routed Events , что фактически означает, что ваш Canvas
будет получать события от самого холста и всего, что находится внутри холста.Как вы заметили, событие Canvas
PreviewMouseMove
получает события как от Canvas
, так и от Rectangle
.
[Обновить] Я запустил ваш код и добавил строку для проверки значенияиз e.OriginalSource
, чтобы увидеть, что первоначально вызвало событие.Например:
private void pMouseMove(object sender, MouseEventArgs e)
{
// print out e.OriginalSource just for learning purposes
Console.WriteLine("OriginalSource:" + e.OriginalSource.ToString());
}
Мой первоначальный ответ - проверить тип e.OriginalSource, потому что я думал, что вы получаете одно и то же событие дважды.Но теперь я понимаю, что вы говорите: если e.OriginalSource
является Rectangle
, событие PreviewMouseMove
возникает в два раза чаще по сравнению с тем, когда e.OriginalSource
является Canvas
.Есть что-то внутреннее в реализации Rectangle
, которая делает это (единственный способ выяснить это - использовать инструмент, такой как Reflector, чтобы увидеть внутреннюю логику. Однако есть обходной путь, в котором вы можете сделать частоту события согласованной.
Вы можете установить rect.IsHitTestVisible = false;
, и это исключит Прямоугольник из отправки событий и будет e.OriginalSource
- это означает, что все PreviewMouseMove
события будут поступать из Canvas
. Затем вы можете использовать VisualTreeHelper.HitTest
, чтобы проверить, находится ли позиция мыши внутри Rectangle
.
. Я только что запустил этот код ниже, и я думаю, что это способ гарантировать последовательное возбуждение событий, но при этом у вас есть возможность теста на попадание.
В конструкторе:
rect.Fill = Brushes.Black;
rect.IsHitTestVisible = false;
Can.Children.Add(rect);
В обработчике PreviewMouseMove
:
private void pMouseMove(object sender, MouseEventArgs e)
{
// Debug.WriteLine(e.OriginalSource.ToString());
HitTestResult result = VisualTreeHelper.HitTest(rect, e.GetPosition(sender as UIElement));
if (result != null) {
Debug.WriteLine("Mouse inside rect")
}
else {
Debug.WriteLine("Mouse outside rect");
}
}