This is a migrated thread and some comments may be shown as answers.

InvalidOperationException when showing Backstage a second time

7 Answers 180 Views
RibbonView and RibbonWindow
This is a migrated thread and some comments may be shown as answers.
Matt
Top achievements
Rank 1
Matt asked on 03 Jul 2015, 09:36 PM

Hi there,

I am experiencing an intermittent InvalidOperationException when attempting to show the backstage of a RadRibbonView for the second or subsequent time.

The cause seems to be that the backstage control has not been properly removed from the BackstageAdorner to which it was originally added.

Unfortunately, all of the functionality is either private or internal so it does not appear as though there is any way I can code around this.

Any suggestions would be greatly appreciated.

 

Thanks.

 

Here is the call stack related to the error. (since .txt attachments aren't allowed?)

  PresentationFramework.dll!System.Windows.FrameworkElement.ChangeLogicalParent(System.Windows.DependencyObject newParent) Unknown
  PresentationFramework.dll!System.Windows.FrameworkElement.AddLogicalChild(object child) Unknown
> Telerik.Windows.Controls.RibbonView.dll!Telerik.Windows.Controls.RibbonView.BackstageAdorner.BackstageAdorner(System.Windows.FrameworkElement adornedElement, Telerik.Windows.Controls.RadRibbonBackstage backstage, double topOffset) Line 30 C#
  Telerik.Windows.Controls.RibbonView.dll!Telerik.Windows.Controls.RadRibbonView.CreateBackstageAdorner() Line 1419 C#
  Telerik.Windows.Controls.RibbonView.dll!Telerik.Windows.Controls.RadRibbonView.ShowBackstage() Line 2536 C#
  Telerik.Windows.Controls.RibbonView.dll!Telerik.Windows.Controls.RadRibbonView.ToggleIsBackstageOpen() Line 2655 C#
  Telerik.Windows.Controls.RibbonView.dll!Telerik.Windows.Controls.RadRibbonView.OnIsBackstageOpenChanged(System.Windows.DependencyObject d, System.Windows.DependencyPropertyChangedEventArgs e) Line 1960 C#
  WindowsBase.dll!System.Windows.DependencyObject.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e) Unknown
  PresentationFramework.dll!System.Windows.FrameworkElement.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e) Unknown
  WindowsBase.dll!System.Windows.DependencyObject.NotifyPropertyChange(System.Windows.DependencyPropertyChangedEventArgs args) Unknown
  WindowsBase.dll!System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex entryIndex, System.Windows.DependencyProperty dp, System.Windows.PropertyMetadata metadata, System.Windows.EffectiveValueEntry oldEntry, ref System.Windows.EffectiveValueEntry newEntry, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType) Unknown
  WindowsBase.dll!System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty dp, object value, System.Windows.PropertyMetadata metadata, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType, bool isInternal) Unknown
  WindowsBase.dll!System.Windows.DependencyObject.SetValue(System.Windows.DependencyProperty dp, object value) Unknown
  Telerik.Windows.Controls.RibbonView.dll!Telerik.Windows.Controls.RadRibbonView.IsBackstageOpen.set(bool value) Line 667 C#
  Telerik.Windows.Controls.RibbonView.dll!Telerik.Windows.Controls.RadRibbonView.AppButtonMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) Line 1258 C#
  PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) Unknown
  PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown
  PresentationCore.dll!System.Windows.UIElement.ReRaiseEventAs(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args, System.Windows.RoutedEvent newEvent) Unknown
  PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) Unknown
  PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown
  PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) Unknown
  PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) Unknown
  PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() Unknown
  PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) Unknown
  PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawMouseActions actions, int x, int y, int wheel) Unknown
  PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd, MS.Internal.Interop.WindowMessage msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
  PresentationCore.dll!System.Windows.Interop.HwndSource.InputFilterMessage(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
  WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
  WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown
  WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
  WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) Unknown
  WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown
  WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) Unknown
  [Native to Managed Transition] 
  [Managed to Native Transition] 
  WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Unknown
  PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Unknown
  PresentationFramework.dll!System.Windows.Application.Run() Unknown
  ocontrol.exe!TracRite.Optimum.App.Main() C#

7 Answers, 1 is accepted

Sort by
0
Peshito
Telerik team
answered on 07 Jul 2015, 08:20 AM
Hello Matt,

Thank you for sharing the stack trace. It is however not enough to isolate the issue and provide solution for it. I tried to reproduce it but to no avail. Could you send us a sample runnable project reproducing this behavior which I will be able to debug locally and later assist you. As this is a forum post, you could either submit a new support ticket and attach it there or use this thread and a third party web site for files sharing.

Regards,
Peshito
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Matt
Top achievements
Rank 1
answered on 07 Jul 2015, 08:50 PM

Hi Peshito,

Unfortunately I cannot reproduce this in a small scale project, although it happens readily in our full application.

After debugging the issue with decompiled assemblies, I can tell that it is happening due to the backstage not being removed as the logical/visual child of the Telerik.Windows.Controls.RibbonView.BackstageAdorner.  The BackstageAdorner relies on the OnUnloaded method being called in response to the Unloaded event firing to remove the backstage properly.  For some reason, that method is not being called in a timely manner and the next time the backstage is displayed the error I provided above is produced.

The easiest way I can think to fix this is to specifically remove the backstage from the BackstageAdorner at the same time as the BackstageAdorner is being removed from the AdornerLayer (in RadRibbonView.HideBackstage).  Another option is to not re-create the BackstageAdorner every time the backstage is shown.

0
Peshito
Telerik team
answered on 08 Jul 2015, 11:22 AM
Hello Matt,

I am glad you managed to solve where the issue came from and to come up with a solution. As this is something that could be a bug in our control I would ask you anyway if you manage to isolate it further please send us the sample so we could investigate it and provide a fix if necessary.

Regards,
Peshito
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Matt
Top achievements
Rank 1
answered on 08 Jul 2015, 02:48 PM

Hi Peshito,

Although I know how to fix it, unfortunately I cannot as all the functionality is either private or internal.  Both the RadRibbonView.HideBackstage method and the BackstageAdorner classes are internal so I have no option to subclass and override the functionality.  As it stands, I'm at a bit of an impasse.  I either have to rip out the RadRibbonView in favor of the stock MS Ribbon control and create my own backstage control, or I have to re-code the Telerik controls from the source.  Neither is a good solution as far as I'm concerned.

What would you suggest?

0
Kiril Vandov
Telerik team
answered on 13 Jul 2015, 12:08 PM
Hello Matthew,

Thank you for your cooperation.
I can agree that the two solutions are not good and we prefer to fix such issue in the code of the ribbon so all clients can take advantage. That is why we are trying to reproduce the issue on our side in order to do out best to fix the issue. However I have spend a lot of time trying to reproduce the issue, but with no success. That is why I would like to ask you for a little more details about your scenario:
- you said that it happens only when you try to open the backstage for second time : Do you have any application logic connected to any of the RibbonBackstage event (loaded/unload/selection ... e.t)?
- do you have custom styles for the RibbonBackstage or the BackstageItem?
- do you inherit either of the RibbonBackstage or the BackstageItem controls ?
- do you execute some of your logic in a Dispatcher or another Tread ?

Looking forward to hearing from you.

Kind regards,
Kiril Vandov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Matt
Top achievements
Rank 1
answered on 13 Jul 2015, 07:38 PM

Hi Kiril,

Here are some answers to the questions above:

1.) Yes, we have application logic to handle both the Loaded and Unloaded events of the RibbonBackstage.  All we're doing in these is setting a Boolean variable (not a dependency property) to indicate whether or not to continue tracking selection changes of the host Ribbon. We also have an event handler for the RadRibbonView.ApplicationMenuOpenStateChanged event which collapses an expander containing a WebBrowser control as the WebBrowser displays over the RibbonBackstage when the backstage is displayed.

2.) No, we are not using custom styles for either of these controls.  We do have a custom control as the content of the BackstageItems, however when I re-created the control hierarchy in a test project, the exception above was not thrown which leads me to believe that the custom controls are not the issue.  And yes, the error still occurs when these controls are not present.

3.) No, we are using the stock controls as provided.

4.) All UI logic is performed either directly on the main UI thread or by being invoked on a control's dispatcher.  In this case, the backstage contents are already defined when the RibbonBackstage is created and applied and nothing is being run through a dispatcher or a background thread.

 

I took the time to implement the workaround I suggested above (explicitly removing the backstage from the BackstageAdorner) and can verify that this does resolve the issue.  While debugging the issue initially, I tried to think of the different ways in which a control may not be loaded/unloaded correctly.  In this case, we have nothing holding on to an instance of the BackstageAdorner and no Exceptions are being generated while hiding the Backstage (verified by adding all CLR exceptions to the 'break when thrown' list).  The behavior that I've noticed is as follows:
1 - click the ribbon's application button
2 - backstage appears
3 - click a ribbon tab or click the ribbon's application button again to hide the backstage
4 - click the ribbon's application button to re-display the backstage
5 - backstage fails to open
6 - click the ribbon's application button to re-display the backstage
7 - exception

So, it may be that the issue is not with the BackstageAdorner not unloading but instead with it not being loaded.  Either way, no exceptions were thrown to indicate a potential cause when the backstage failed to open at step 5.

0
Kiril Vandov
Telerik team
answered on 15 Jul 2015, 03:36 PM
Hello Matt,

Thank you for the detailed information. I have tried to reproduce the issue with the updated information but with no success. I will continue trying to and will contact you if we succeed.
However I would like you to try and test your application if you have empty backstage items as the content of the items might be somehow connected. Also I would like to ask you for the exact version of binaries that you are using and if they are Xaml or NoXaml.

Thank you for your cooperation.

Kind regards,
Kiril Vandov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
RibbonView and RibbonWindow
Asked by
Matt
Top achievements
Rank 1
Answers by
Peshito
Telerik team
Matt
Top achievements
Rank 1
Kiril Vandov
Telerik team
Share this question
or