This is an old topic but I thought I'd post an answer in case anyone else comes across it from a web search.
When deserializing, new LayoutAnchorable objects are created without a name registered, that's why your code doesn't work anymore, you are acting on non existent LayoutAnchorables.
You can unregister and re-register the names if you want, but it basically becomes irrelevant to register a name for the LayoutAnchorable object.
The best way to get around this is to use the mvvm pattern and follow the examples provided, it works beautifully. If you are stuck, like I was for this specific application, here is an example. To re-iterate, this is not the best practice IMO, but a hacky workaround.
Lets say I have a LayoutAnchorable with a content id "myContentId", I have a menu item set to show and hide it, with the IsChecked property of the MenuItem showing the visible state. I'll set an initial DataContext for clarity.
The click event looks like this and can be used for all the menu items you have that show and hide LayoutAnchorables:
Now when I deserialize, a new LayoutAnchorable is created and the DataContext is lost for the menu item.
To fix this, I need to reapply the DataContext on the deserialization callback:
If you need access to the LayoutAnchorable from other methods in code behind, you can just grab the DataContext of the MenuItem you know is bound to it or you can unregister and reregister the name during deserialization then search for it by name when you need it.
Example of unregister and re-registering the name:
Then to find it don't use this.myLayoutAnchorable, you have to search for it:
Hope this helps.
When deserializing, new LayoutAnchorable objects are created without a name registered, that's why your code doesn't work anymore, you are acting on non existent LayoutAnchorables.
You can unregister and re-register the names if you want, but it basically becomes irrelevant to register a name for the LayoutAnchorable object.
The best way to get around this is to use the mvvm pattern and follow the examples provided, it works beautifully. If you are stuck, like I was for this specific application, here is an example. To re-iterate, this is not the best practice IMO, but a hacky workaround.
Lets say I have a LayoutAnchorable with a content id "myContentId", I have a menu item set to show and hide it, with the IsChecked property of the MenuItem showing the visible state. I'll set an initial DataContext for clarity.
<MenuItemHeader="_Detail"Name="mnuDetailWindow"DataContext="{Binding ElementName=myLayoutAnchorable}"IsCheckable="True"IsChecked="{Binding Path=IsHidden, Mode=OneWay, Converter={StaticResource InvertBool}}"Click="mnuWindowShowHide_Click"/>
///<summary>/// Show/Hide dockable window///</summary>///<param name="sender"></param>///<param name="e"></param>privatevoid mnuWindowShowHide_Click(object sender, RoutedEventArgs e) { MenuItem menu = sender as MenuItem; LayoutAnchorable dockable = menu.DataContext as LayoutAnchorable; if (dockable.IsHidden) { dockable.Show(); } else { dockable.Hide(); } }
To fix this, I need to reapply the DataContext on the deserialization callback:
void serializer_LayoutSerializationCallback(object sender, Xceed.Wpf.AvalonDock.Layout.Serialization.LayoutSerializationCallbackEventArgs e) { if (e.Model != null) { switch(e.Model.ContentId) { //Do this for each LayoutAnchorable that has a menu item to show/hide itcase"myContentId": this.mnuDetailWindow.DataContext = e.Model; break; default: break; } } }
Example of unregister and re-registering the name:
//Do this during the deserializationif (Application.Current.MainWindow.FindName("myLayoutAnchorable") != null) { Application.Current.MainWindow.UnregisterName("myLayoutAnchorable"); } Application.Current.MainWindow.RegisterName("myLayoutAnchorable", e.Model);
LayoutAnchorable anchorable = this.FindName("myLayoutAnchorable") as LayoutAnchorable;