In WPF, under what circumstances does Visual.PointFromScreen throw InvalidOperationException?
There's a static method PresentationSource.FromVisual
which:
Returns the source in which a provided Visual is presented.
I know this doesn't solve the underlying problem, but you could check that the Visual is connected to a PresentationSource before calling PointFromScreen
. It would prevent the exception, but you'd need to do some more investigation as to why it wasn't connected in the first place.
I had a similar problem with a custom-made visual.
The solution was to defer the problematic task via Dispatcher (deferred execution with background priority in this case)...
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);
}
I've used that PostCall in other ScrollViewer related rendering situations.
I've found you can test IsVisible
before calling PointFromScreen
to protect against the InvalidOperationException
.