Предположим, что я хотел сделать это, таким образом, я могу найти текущую позицию мыши относительно a Visual
, не нуждаясь в доступе к определенному событию от нажатия мыши:
public static Point GetMousePosition(this Visual relativeTo)
{
return relativeTo.PointFromScreen(GetMousePositionOnScreen());
}
Иногда (обычно, когда я только что переключился между двумя средствами управления вкладкой), PointFromScreen
броски InvalidOperationException
с сообщением Это Визуальное не подключено к PresentationSource.
При рассмотрении свойств, доступных на Visual
Я не вижу, что любой касается a PresentationSource
.
Данный a Visual
, как я могу сказать, собирается ли это выдать то исключение, когда я звоню PointFromScreen
на нем?
Существует статический метод Председания. Известный
, который:
возвращает источник, в котором представлен прилагаемый визуальный вариант.
Я знаю, что это не решает базовую проблему, но вы могли бы проверить, что визуальный вариант подключен к представлению до вызова PointFromscreen
. Это предотвратит исключение, но вам нужно было сделать еще несколько расследований по отношению к тому, почему он не был связан в первую очередь.
У меня была аналогичная проблема с созданным на заказ визуалом.
Решением было отложить проблемную задачу через Dispatcher (в данном случае отложенное выполнение с приоритетом фона) ...
public void MyProblematicDisplayMethod(Symbol TargetSymbol)
{
this.HostingScrollViewer.BringIntoView(TargetSymbol.HeadingContentArea);
...
// This post-call is needed due to WPF tricky rendering precedence (or whatever it is!).
this.HostingScrollViewer.PostCall(
(scrollviewer) =>
{
// in this case the "scrollviewer" lambda parameter is not needed
var Location = TargetSymbol.Graphic.PointToScreen(new Point(TargetSymbol.HeadingContentArea.Left, TargetSymbol.HeadingContentArea.Top));
ShowOnTop(this.EditBox, Location);
this.EditBox.SelectAll();
});
...
}
/// <summary>
/// Calls, for this Source object thread-dispatcher, the supplied operation with background priority (plus passing the source to the operation).
/// </summary>
public static void PostCall<TSource>(this TSource Source, Action<TSource> Operation) where TSource : DispatcherObject
{
Source.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new DispatcherOperationCallback(delegate(Object state)
{ Operation(Source); return null; }),
null);
}
Я использовал этот PostCall в других ситуациях рендеринга, связанных с ScrollViewer.