Page Index Toggle Pages: [1] 2  Send TopicPrint
Hot Topic (More than 10 Replies) Possible deserialization Issue (Read 12207 times)
Paul Eden
Full Member
***
Offline



Posts: 128
Joined: Aug 15th, 2007
Possible deserialization Issue
Mar 25th, 2009 at 3:20pm
Print Post  
I have a diagram with a custom UserControl in a DiagramNode. The UserControl contains a button. If I serialize the diagram the UserControl (RootNode) gets serialized as follows:

- <RootNode ControlModeId="-1" ControlImage="{x:Null}" LastPosition="0,0" Width="80" Height="50" RenderTransform="1,0,0,1,1,1" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Button Background="#FFFF0000" Name="btnButton">Button</Button>
</RootNode>

When the diagram data is reloaded I get an error saying that the name of the button control has already been registered and cannot be created again.

It would seem that the deserialization process is trying to create the button control that is already created by instancing a new RootNode control. 
Is this by design and a fault with my control?

Many thanks


Paul
  
Back to top
WWW  
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Possible deserialization Issue
Reply #1 - Mar 25th, 2009 at 4:15pm
Print Post  
Hi Paul,

Hosted controls are serialized using the WPF's XalmWriter and XamlReader classes. We'll check if anything can be done to avoid this.

Stoyan
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Possible deserialization Issue
Reply #2 - Mar 31st, 2009 at 7:16am
Print Post  
Hi Paul,

It works fine if you add the following to your user control's constructor:

NameScope.SetNameScope(this, new NameScope());

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Paul Eden
Full Member
***
Offline



Posts: 128
Joined: Aug 15th, 2007
Re: Possible deserialization Issue
Reply #3 - Mar 31st, 2009 at 12:39pm
Print Post  
Thanks for the suggestion.  Unfortunately for us this has no effect - the loading of the XML still generates the same messgae of an already registered name.  As our User Control inherrits from a base class, I added the above to the constructor of the base class too, but again without effect.
  
Back to top
WWW  
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Possible deserialization Issue
Reply #4 - Mar 31st, 2009 at 2:58pm
Print Post  
Have you added this to all constructors of all custom controls you are using? Also, this might work only for newly saved files; we haven't tried saving without a name scope and loading with a name scope. If you still can't get it to run, please email us a small project that reproduces the problem.

Stoyan
  
Back to top
 
IP Logged
 
Paul Eden
Full Member
***
Offline



Posts: 128
Joined: Aug 15th, 2007
Re: Possible deserialization Issue
Reply #5 - Apr 2nd, 2009 at 2:38pm
Print Post  
OK, having found that I had put one call in the wrong place.  We have now serialized and deserialized a very simple diagram with a couple of our user controls.  We are however still having some issues as in some instances a null reference exception is getting thrown:

   at MindFusion.Diagramming.Wpf.Diagram.LoadFromXml(XmlDocument document)
   at MindFusion.Diagramming.Wpf.Diagram.LoadFromString(String str)

I have compared two very similar diagrams using the same controls (one loads the other does not) and cannot seem to see any difference or areas that may create null references - do you have any tools that validate diagram xmls?  I'm happy to send you an XML that does not load but obviously you won't have any of our control DLLs to make proper use of it.


Many thanks


Paul
  
Back to top
WWW  
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Possible deserialization Issue
Reply #6 - Apr 2nd, 2009 at 5:20pm
Print Post  
Does the call stack show where the exception comes from? somewhere in the user controls, or in the diagram code?
  
Back to top
 
IP Logged
 
Paul Eden
Full Member
***
Offline



Posts: 128
Joined: Aug 15th, 2007
Re: Possible deserialization Issue
Reply #7 - Apr 3rd, 2009 at 10:14am
Print Post  
The call stack does not not make any reference to the mindfusion DLL (or the exception generally), but the try-catches are not capturing anything in my object constructors either - as soon as the last control is instanced, the code steps out of my user control code straight into the exception handler around the Diagram.LoadFromString call. My previous post mentioning the exception was truncated by one line (but the last line was my call). For completeness, full exception message as follows:

A first chance exception of type 'System.NullReferenceException' occurred in MindFusion.Diagramming.Wpf.dll
<MyMethodName>:Object reference not set to an instance of an object.
at MindFusion.Diagramming.Wpf.Diagram.LoadFromXml(XmlDocument document)
at MindFusion.Diagramming.Wpf.Diagram.LoadFromString(String str)
at <MyNamespace>.<my control>.<MyMethodName>(String pDiagramData, String pDiagramName) in <reference to line number in my method>

  
Back to top
WWW  
IP Logged
 
Paul Eden
Full Member
***
Offline



Posts: 128
Joined: Aug 15th, 2007
Re: Possible deserialization Issue
Reply #8 - Apr 3rd, 2009 at 10:29am
Print Post  
If I change the exception handling of Visual Studio to stop when exceptions are thrown, the call stack does mention the Mindfusion DLL but again no reference to any exception and the call stack matches the stack trace of the exception.
  
Back to top
WWW  
IP Logged
 
Paul Eden
Full Member
***
Offline



Posts: 128
Joined: Aug 15th, 2007
Re: Possible deserialization Issue
Reply #9 - Apr 3rd, 2009 at 1:00pm
Print Post  
There would also appear to be an issue when controls on the diagram reference styles:

Cannot add content of type 'System.Windows.Style' to an object of type 'System.Windows.ResourceDictionary'.  Error at object 'btnStyle', Line 1 Position 583.

The following code can be used to reproduce this error;

*window xaml*
<Window x:Class="SerializationTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:local="clr-namespace:SerializationTest"
       xmlns:MF="clr-namespace:MindFusion.Diagramming.Wpf;assembly=MindFusion.Diagrammi
ng.Wpf"
    Title="Window1" Height="300" Width="300">
    <Grid>
       <MF:Diagram x:Name="oDiag"/>
    </Grid>
</Window>

*\Window code behind*
    public partial class Window1 : Window
    {
       public Window1()
       {
           InitializeComponent();

           TestControl testControl = new TestControl();
           testControl.Click += new RoutedEventHandler(testControl_Click);

           oDiag.Items.Add(testControl);

           Diagram.SetItemBounds(testControl, new Rect(0, 0, 50, 25));
       }

       void testControl_Click(object sender, RoutedEventArgs e)
       {
           Diagram newDiag = new Diagram();
           
           string diagXml =oDiag.SaveToString(SaveToStringFormat.Xml,true);

           //' exception thrown on this line
           newDiag.LoadFromString(diagXml);

       }
    }


*user control xaml*
<UserControl x:Class="SerializationTest.TestControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="Auto" Width="Auto">
    <UserControl.Resources>
       <Style x:Key="btnStyle" TargetType="{x:Type Button}">
           <Setter Property="Foreground" Value="White" />
       </Style>
    </UserControl.Resources>
    <Grid>
       <Button Style="{StaticResource btnStyle}" Height="25" Width="50" Content="Test button" x:Name="btnTest" />
    </Grid>
</UserControl>

*user control code behind
namespace SerializationTest
{
    /// <summary>
    /// Interaction logic for TestControl.xaml
    /// </summary>
    [Serializable]
    public partial class TestControl : UserControl
    {

       #region Click
           /// <summary>
           /// Routed event to pass out a click event to the main window
           /// </summary>
           public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click",
                                                                                RoutingStrategy.Bubble,
                                                                                typeof(RoutedEvent),
                                                                                typeof(TestControl));

           public event RoutedEventHandler Click
           {
               add { AddHandler(ClickEvent, value); }
               remove { RemoveHandler(ClickEvent, value); }
           }

           void RaiseClickEvent()
           {
               RoutedEventArgs newEventArgs = new RoutedEventArgs(ClickEvent);
               RaiseEvent(newEventArgs);
           }
       #endregion

       public TestControl()
       {
           InitializeComponent();
           btnTest.Click += new RoutedEventHandler(btnTest_Click);
           NameScope.SetNameScope(this, new NameScope());
       }

       void btnTest_Click(object sender, RoutedEventArgs e)
       {
           RaiseClickEvent();
       }


    }
}
  
Back to top
WWW  
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Possible deserialization Issue
Reply #10 - Apr 7th, 2009 at 9:50am
Print Post  
We've managed to make this work by defining the styles in the application resources. The XamlWriter and Reader do not provide much control over the serialization process, so if you prefer defining the styles in the user control, the only thing we can do is add some events to let you serialize the control instances yourself.

Stoyan
  
Back to top
 
IP Logged
 
Paul Eden
Full Member
***
Offline



Posts: 128
Joined: Aug 15th, 2007
Re: Possible deserialization Issue
Reply #11 - Apr 7th, 2009 at 11:57am
Print Post  
Is this solution going to be the same when using resource dictionaries?  I've managed to get the same behaviour in a control libraray and a resource dictionary file referenced in the following manor:

       <ResourceDictionary>
           <ResourceDictionary.MergedDictionaries>
               <ResourceDictionary Source="pack://application:,,,/cControls;Component/Dictionary1.xaml"/>
           </ResourceDictionary.MergedDictionaries>
       </ResourceDictionary>
  
Back to top
WWW  
IP Logged
 
Paul Eden
Full Member
***
Offline



Posts: 128
Joined: Aug 15th, 2007
Re: Possible deserialization Issue
Reply #12 - Apr 22nd, 2009 at 2:46pm
Print Post  
Hi

Not to rush, but is there an asnwer available for this one?


Thanks


Paul
  
Back to top
WWW  
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Possible deserialization Issue
Reply #13 - Apr 23rd, 2009 at 9:06am
Print Post  
We haven't tried this with resource dictionaries. What behavior did you got with them - still throwing the "Cannot add content" exception?
  
Back to top
 
IP Logged
 
Paul Eden
Full Member
***
Offline



Posts: 128
Joined: Aug 15th, 2007
Re: Possible deserialization Issue
Reply #14 - Apr 23rd, 2009 at 9:26am
Print Post  
Yes, the same exception occurrs.

Many thanks

Paul
  
Back to top
WWW  
IP Logged
 
Page Index Toggle Pages: [1] 2 
Send TopicPrint