TabbedMdiContainer doesn't fire SelectionChanged event after dock site layout serialization

Docking/MDI for WPF Forum

Posted 5 years ago by Yaron
Version: 13.1.0058
Avatar

Hello!  My scenario is firstly to save the dock site layout of my TabbedMdiContainer control by using DockSiteLayoutSerializer.SaveToString() method to get a string for the layout. And then I need to load this string and restore the view by using DockSiteLayoutSerializer.LoadFromString() method. But after this, the refreshed TabbedMdiContainer control doesn't work to fire SelectionChaged event. The related data binding on SelectedTabIndex doesn't work either. As I have a big work based on the SelectionChanged mechanism, so my work just stopped now. Can anyone help me on that? thanks so much!!

And I've made an example project to demo this problem, but where am I supposed to upload my sample project?


 

Sorry I didn't make my story clear. Just forget about the event,  let's just focus on the data binding, my data binding for the SelectedTabIndex property of TabbedMdiContainer control just doesn't work. The SelectedTabIndex value kept being -1. And even I did click to switch the tab, the set method of the bound property in my viewmodel didn't been triggerred. I made an example project to show what I'm talking about. Is there any way that I can send it to you?

And I've uploaded my example project code into OnDrive. Please try getting the zipped file TabEvent.zip by this link: http://1drv.ms/1DrljKI

If this way is not what you always do for providing example project, please just give me a way to upload my code. Thanks a lot.

[Modified 5 years ago]

Comments (5)

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

You should never keep references to any "containers" like SplitContainer, ToolWindowContainer, or TabbedMdiContainer. All of those controls are completely transient and will be dynamically created/destroyed as required for any layout change or docking operation. In this case, your layout load is likely clearing the layout and making brand new TabbedMdiContainers to use.

You could use various events on DockSite instead, such as WindowActivated. That would fire anytime a window gets focus.


Actipro Software Support

Posted 5 years ago by Yaron
Avatar

Sorry I didn't make my story clear. Just forget about the event, let's just focus on the data binding, my data binding for the SelectedTabIndex property of TabbedMdiContainer control just doesn't work. The SelectedTabIndex value kept being -1. And even I did click to switch the tab, the set method of the bound property in my viewmodel didn't been triggerred. I made an example project to show what I'm talking about. Is there any way that I can send it to you?

And I've uploaded my example project code into OnDrive. Please try getting the zipped file TabEvent.zip by this link: http://1drv.ms/1DrljKI

this way is not what you always do for providing example project, please just give me a way to upload my code. Thanks a lot.

[Modified 5 years ago]

Answer - Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Yaron,

Thanks for the sample.  For future reference, if you have a sample, please rename the .zip file extension so it doesn't get spam blocked, and email it to our support address with the full repro steps of the issue.

Per our reply above, you can't do this sort of thing.  You are binding to a specific TabbedMdiContainer via:

<docking:TabbedMdiContainer SelectedIndex="{Binding SelectedTabIndex, Mode=TwoWay}"> ...

You cannot do that sort of thing because all TabbedMdiContainer objects are transient and dynamically get created/destroyed on various layout changes.  When you deserialize a layout, all the containers are removed from the UI and new ones are made.  So your Binding still references an old TabbedMdiContainer after layout deserialization that is no longer in the UI or has any content.  That's why the SelectedIndex is -1.

The TabbedMdiContainer would also fully go out of UI scope if you closed all documents one by one and then opened a new document.  In that case, a new TabbedMdiContainer would be in place, similar to what happens during layout deserialization.

You should track the DockSite events like WindowActivated.  Or you can remove that TabbedMdiContainer SelectedIndex binding and do a binding like this on your VM instead:

{Binding ElementName=dockSite, Path=ActiveWindow}


Actipro Software Support

Posted 5 years ago by Yaron
Avatar

Thanks. I changed to use WindowActived event and it works.  But I'm still curious that what's the difference of SelectionChanged event and WindowActived event. Why this WindowActivated can still work after the deserialization?

[Modified 5 years ago]

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

SelectionChanged is an event on a transient container control while WindowActivated is on the DockSite.  The DockSite is a persistent control that doesn't change based on layout updates.  That's why events on DockSite or a docking window are reliable to watch.  MDI host controls are also reliable as long as you keep the same MDI host control in place (don't manually change MDI styles).


Actipro Software Support

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.