Я визуализирую сетку WPF с несколькими элементами (кнопки, текстовое поле,...) в растровое изображение, которое затем используется в качестве текстуры для трехмерной поверхности в сцене Direct3D. Для взаимодействия с пользователем я создаю 3D-луч из положения 2D-курсора мыши в 3D-сцену, находя точку пересечения с поверхностью графического интерфейса. Итак, я знаю, где пользователь щелкнул сетку WPF, но оттуда я застрял:
Как я могу имитировать события мыши на элементах WPF, когда они фактически не отображаются в открытом окне, а отображаются за пределами экрана?
Недавно я изучал UIAutomation и RaiseEvent, но они используются для отправки событий отдельным элементам, а не всему визуальному дереву. Обход дерева вручную и поиск элементов в позиции курсора был бы вариантом, но я не нашел способа сделать это точно. VisualTreeHelper.HitTest — хорошее начало, но вместо TextBox он находит TextBoxView, а вместо ListBox — Border.
РЕДАКТИРОВАТЬ: возврат HitTestResultBehavior.Continue в обратном вызове результата HitTest позволяет мне пройти через все элементы в заданной точке. Теперь я могу отправлять события мыши всем этим элементам, но значения объекта MouseEventArgs совпадают со значениями реальной мыши. Поэтому мне нужно создать собственный MouseDevice, что, по-видимому, невозможно.
PointHitTestParameters p = new PointHitTestParameters(new Point(
((Vector2)hit).X * sourceElement.ActualWidth,
(1 - ((Vector2)hit).Y) * sourceElement.ActualHeight));
VisualTreeHelper.HitTest(sourceElement,
new HitTestFilterCallback(delegate(DependencyObject o)
{
return HitTestFilterBehavior.Continue;
}),
new HitTestResultCallback(delegate(HitTestResult r)
{
UIElement el = r.VisualHit as UIElement;
if (el != null)
{
MouseButtonEventArgs e = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left);
if (leftMouseDown) e.RoutedEvent = Mouse.MouseDownEvent;
else e.RoutedEvent = Mouse.MouseUpEvent;
el.RaiseEvent(e);
}
return HitTestResultBehavior.Continue;
}), p);