Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Loading CompositeNodes (Read 2109 times)
Rich Cassell
Junior Member
**
Offline


I Love MindFusion!

Posts: 63
Joined: Sep 19th, 2012
Loading CompositeNodes
Nov 6th, 2012 at 10:30am
Print Post  
Hey!

I've decided to use CompositeNodes instead of simple DiagramNodes because of needing to show more information on them. One of our user requirements is to allow them to change the title and text of a node to be more relevant to it's purpose on a diagram.

When i add a new node onto the diagram i can use my context menu to change it's title and it's text and it works fine (It also saves the new values)... But if i load nodes from XML it creates them correctly (with the right contents) but doesn't change when the user enters new details...

I have looked at the _title and _text TextComponents that are being created when loading my *new* nodes from XML and they are always empty upon creation - even though the node shows the correct information from the XML. So now i'm confused.

I hope this makes sense - any help will be ace!

Regards,
Rich Smiley
  
Back to top
 
IP Logged
 
Meppy
God Member
*****
Offline


MindFusion support

Posts: 1783
Joined: Jul 20th, 2005
Re: Loading CompositeNodes
Reply #1 - Nov 6th, 2012 at 11:11am
Print Post  
Hi,

You need to make sure that the _text and _title members are updated to reference the proper components after the node is loaded. You can do this by using the FindComponent method of the CompositeNode class.

If this doesn't help, please attach a small sample project that illustrates the problem.

Regards,
Meppy
  
Back to top
 
IP Logged
 
Rich Cassell
Junior Member
**
Offline


I Love MindFusion!

Posts: 63
Joined: Sep 19th, 2012
Re: Loading CompositeNodes
Reply #2 - Nov 6th, 2012 at 11:21am
Print Post  
Hi Meppy,

Thanks for your reply. Yeah i'm using the FindComponent method and then looking at the members afterwards and although they're not "Nothing" the relevant values are left unpopulated - almost like new, empty TextComponents...

The stuff is quite embedded into my project and it's going to be very difficult to attach a small project... But, below is the code for my node class - perhaps the problem exists in there somewhere....

Code
Select All
<Serializable()>
Public Class FlowNodeDesign
    Inherits CompositeNode

    Private _shape As ShapeComponent
    Private _image As ImageComponent
    Private _title As TextComponent
    Private _text As TextComponent

    Public Sub New(ByVal diagram As Diagram)

        MyBase.new(diagram)

        Dim content As String = _
            "<SimplePanel>" & _
            "" & _
            "  <Shape Name=""Shape"" Shape=""RoundRect"" />" & _
            "" & _
            "  <Border Padding=""2"">" & _
            "    <GridPanel>" & _
            "      <GridPanel.Columns>" & _
            "        <GridColumn Width=""20"" />" & _
            "        <GridColumn />" & _
            "      </GridPanel.Columns>" & _
            "      <GridPanel.Rows>" & _
            "        <GridRow />" & _
            "      </GridPanel.Rows>" & _
            "" & _
            "      <Image Name=""Image"" ImageAlign=""Fit"" />" & _
            "" & _
            "      <StackPanel Orientation=""Vertical"" GridColumn=""1"">" & _
            "        <Text Name=""Title"" Font=""Arial, 12pt, style=Bold"" TextAlignment=""Near"" />" & _
            "        <Text Name=""Text"" Font=""Arial, 8pt"" TextAlignment=""Near"" />" & _
            "      </StackPanel>" & _
            "    </GridPanel>" & _
            "  </Border>" & _
            "" & _
            "</SimplePanel>"

        Components.Add(MindFusion.Diagramming.Components.XmlLoader.Load(content, Nothing, Nothing))

        _shape = CType(FindComponent("Shape"), ShapeComponent)
        _image = CType(FindComponent("Image"), ImageComponent)
        _title = CType(FindComponent("Title"), TextComponent)
        Debug.WriteLine(_title.Text)
        _text = CType(FindComponent("Text"), TextComponent)

        Stroke = New MindFusion.Drawing.Pen(Color.Black, 0)
        Fill = New MindFusion.Drawing.SolidBrush(Color.White)
    End Sub

    Public Property Stroke() As MindFusion.Drawing.Pen

        Get
            Return _shape.Pen
        End Get
        Set(ByVal value As MindFusion.Drawing.Pen)
            _shape.Pen = value
        End Set

    End Property

    Public Property Fill() As MindFusion.Drawing.Brush

        Get
            Return _shape.Brush
        End Get
        Set(ByVal value As MindFusion.Drawing.Brush)
            _shape.Brush = value
        End Set

    End Property

    Public Property Image() As Image

        Get
            Return _image.Image
        End Get
        Set(ByVal value As Image)
            _image.Image = value
        End Set

    End Property

    Public Property Title() As String

        Get
            Return _title.Text
        End Get
        Set(ByVal value As String)
            _title.Text = value
        End Set

    End Property

    Public Property Text() As String

        Get
            Return _text.Text
        End Get
        Set(ByVal value As String)
            _text.Text = value
        End Set

    End Property
End Class
 



Regards,
Rich Smiley
  
Back to top
 
IP Logged
 
Meppy
God Member
*****
Offline


MindFusion support

Posts: 1783
Joined: Jul 20th, 2005
Re: Loading CompositeNodes
Reply #3 - Nov 6th, 2012 at 1:27pm
Print Post  
Hi,

The CompositeNode serialization is designed to work in two modes.

In the first (the default) mode, the composite nodes serialize their entire component hierarchy during saves and completely rebuild the component hierarchy during load. When using this mode, all references to components need to be updated after a node has been loaded because the component hierarchy has been replaced and the old component references are no longer relevant. To do this, override the LoadFromXml method of the CompositeNode class:

Code
Select All
Protected Overrides Sub LoadFromXml(xmlElement As System.Xml.XmlElement, context As XmlPersistContext)
	MyBase.LoadFromXml(xmlElement, context)

	_title = CType(FindComponent("Title"), TextComponent)
	_text = Ctype(FindComponent("Text"), TextComponent)
End Sub 


However, due to a bug in the current deserialization logic, the old hierarchy is not removed during load and the new hierarchy is added alongside. Because of this, FindComponent will still return references to the old hierarchy. To fix this, you can call Components.Clear before invoking the base LoadFromXml. This bug will be fixed in the upcoming 6.0.1 release.

In the second serialization mode, the component hierarchy is not serialized. Instead of serializing the entire hierarchy, the client is expected to manually save/load only the variable values. This mode has the advantage of keeping the output file smaller and is recommended for cases such as yours, where the component hierarchy is statically defined for all instances of the CompositeNode class. To turn this mode on, override the SerializeComponents method and return False. Then, to manually save and load the variables, override SaveToXml and LoadFromXml and perform the necessary calls through the supplied XmlPersistContext:

Code
Select All
Protected Overrides Function SerializeComponents() As Boolean
	Return False
End Function

Protected Overrides Sub SaveToXml(xmlElement As System.Xml.XmlElement, context As XmlPersistContext)
	MyBase.SaveToXml(xmlElement, context)

	context.WritePen(Stroke, "ComponentStroke", xmlElement)
	context.WriteBrush(Fill, "ComponentFill", xmlElement)
	context.WriteImage(Image, "ComponentImage", xmlElement)
	context.WriteString(Title, "ComponentTitle", xmlElement)
	context.WriteString(Text, "ComponentText", xmlElement)
End Sub

Protected Overrides Sub LoadFromXml(xmlElement As System.Xml.XmlElement, context As XmlPersistContext)
	MyBase.LoadFromXml(xmlElement, context)

	Stroke = context.ReadPen("ComponentStroke", xmlElement)
	Fill = context.ReadBrush("ComponentFill", xmlElement)
	Image = context.ReadImage("ComponentImage", xmlElement)
	Title = context.ReadString("ComponentTitle", xmlElement)
	Text = context.ReadString("ComponentText", xmlElement)
End Sub 


Note that there is no need to update the _title and _text references in this case since the component hierarchy has not changed during load. Also note that only the relevant values are written in the output XML file - the component hierarchy is no longer persisted.

I hope this clarifies things a bit.

Regards,
Meppy
  
Back to top
 
IP Logged
 
Rich Cassell
Junior Member
**
Offline


I Love MindFusion!

Posts: 63
Joined: Sep 19th, 2012
Re: Loading CompositeNodes
Reply #4 - Nov 6th, 2012 at 1:43pm
Print Post  
Hi Meppy!

Thanks for your clarifications. It makes much more sense now.

As per your suggestion i used the second method and that works perfectly now! Thanks very much for your assistance.

Regards,
Rich Smiley
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint