Я рендерим сетку WPF с несколькими элементами (кнопками, текстовым полем, ...) в растровое изображение, которое затем используется в качестве текстуры для трехмерной поверхности в сцене Direct3D. Для взаимодействия с пользователем я создаю 3D-луч из положения курсора 2D-мыши в 3D-сцену, находя точку пересечения с поверхностью графического интерфейса. Итак, я знаю, где пользователь нажал на сетку WPF, но оттуда я застрял:
Как я могу имитировать события мыши на элементах WPF, когда они на самом деле не отображаются в открытом окне, а отображаются вне экрана?
Недавно я изучал UIAutomation и RaiseEvent, но они используются для отправки событий отдельным элементам, а не всему визуальному дереву. Обходить дерево вручную и искать элементы в позиции курсора было бы вариантом, но я не нашел способа сделать это точно. VisualTreeHelper.HitTest - хорошее начало, но вместо поиска TextBox он находит TextBoxView и вместо ListBox находит границу.
РЕДАКТИРОВАТЬ: возвращая HitTestResultBehavior. Продолжение в результате обратного вызова 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);