Author Topic: serialize collectionBase  (Read 6617 times)

0 Members and 1 Guest are viewing this topic.

Draftek

  • Guest
serialize collectionBase
« on: November 28, 2007, 10:09:25 AM »
I need a strongly typed collection of an object I'm building. I derive from collectionbase and all is good except I cannot seem to serialize the collection.

Am I going to have to implement some serializing interfaces?

Glenn R

  • Guest
Re: serialize collectionBase
« Reply #1 on: November 28, 2007, 10:19:01 AM »
Code?

Glenn R

  • Guest
Re: serialize collectionBase
« Reply #2 on: November 28, 2007, 10:20:34 AM »
Also, what version of AutoCAD and the framework?

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: serialize collectionBase
« Reply #3 on: November 28, 2007, 10:33:09 AM »
The last paragraph of this is 'interesting' ..
http://www.mattberther.com/2004/09/05/implementing-collectionbase/
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Draftek

  • Guest
Re: serialize collectionBase
« Reply #4 on: November 28, 2007, 10:33:37 AM »
The object:
Code: [Select]
[Serializable]
    public enum LiteType
    {
        Row,
        Col,
        Main
    }
    /// <summary>
    /// Container for the dlo lite object
    /// </summary>

    [XmlRootAttribute("Lite", Namespace = "", IsNullable = false)]
    public class cLite
    {
        #region private members

        private cLite m_parentLite = null;
        private cLites m_childLites;
        private string m_Name = "";
        private LiteType m_liteType;
        private double m_Width = 0;
        private double m_Height = 0;
        private double m_SillOffset = 0;
       
        #endregion

        #region public members
        // the parent lite or null if this is the root note
        [XmlElementAttribute("parentLite", typeof(cLite))]
        public cLite ParentLite
        {
            get { return m_parentLite; }
            set { m_parentLite = value; }
        }

        // the name string
        [XmlElementAttribute("Name")]
        public string Name
        {
            get { return m_Name; }
            set { m_Name = value; }
        }
        // the child lites collection
        [XmlArray("childLites"),
        XmlArrayItem("childLite", typeof(cLite))]
        public cLites ChildLites
        {
            get { return m_childLites; }
            set { m_childLites = value; }
        }

        [XmlElementAttribute("LiteType", typeof(LiteType))]
        public LiteType liteType
        {
            get { return m_liteType; }
            set { m_liteType = value; }
        }

        [XmlElementAttribute("Width")]
        public double Width
        {
            get { return m_Width; }
            set { m_Width = value; }
        }
        [XmlElementAttribute("Height")]
        public double Height
        {
            get { return m_Height; }
            set { m_Height = value; }
        }

        // the offset of the bottom of the lite - this is used so we can drop
        // the jamb members for a door that would run down to the floor, ignoring
        // any sill gap
        // These would only be used in the vertical sense of the primary children
        // basically the initial rows of the mark
        [XmlElementAttribute("SillOffset")]
        public double SillOffset
        {
            get { return m_SillOffset; }
            set { m_SillOffset = value; }
        }

        #endregion
        // default constructor
        public cLite() :this("No Name", 0, 0, LiteType.Main)
        {
           // default constructor calls the other one
        }
        // constructor to use
        public cLite(string name, double Width, double Height, LiteType lType)
        {
            m_Name = name;
            m_Width = Width;
            m_Height = Height;
            m_liteType = lType;
            m_childLites = new cLites(this);
        }
    }
The collection:
Code: [Select]
// this is basically the child lites collection
    [Serializable]
    public class cLites :CollectionBase
    {

        // constructor - when the collection is created, you need a parent lite
        // to add to all of the children created from the add method
        public cLites(cLite parent)
        {
            m_parentLite = parent;
        }
        #region private members
        // parent lite
        private cLite m_parentLite;
        #endregion

        #region public Members
        [XmlElementAttribute("parentLite", typeof(cLite))]
        public cLite ParentLite
        {
            get { return m_parentLite; }
            set { m_parentLite = value; }
        }
        #endregion
        // the collection stuff
        public int Add(cLite child)
        {
            child.ParentLite = m_parentLite;
            return List.Add(child);
        }
        public void Remove(cLite child)
        {
            List.Remove(child);
           
        }
        public void Insert(int index, cLite child)
        {
            List.Insert(index, child);
        }
        public cLite this[int index]
        {
            get { return (cLite)List[index]; }
            set { List[index] = value; }
        }

    }
Good point on the framework - 2.0
No autocad required

Draftek

  • Guest
Re: serialize collectionBase
« Reply #5 on: November 28, 2007, 10:39:05 AM »
I stumbled on a workaround - wrapping the collection and then serializing the wrapper. It works but I don't know. Apparently there is a problem with the IList interface and serialization.

Draftek

  • Guest
Re: serialize collectionBase
« Reply #6 on: November 28, 2007, 10:41:02 AM »
Sorry Kerry, didn't see your post. I'm not sure how that will help my case since I need an object.

Glenn R

  • Guest
Re: serialize collectionBase
« Reply #7 on: November 28, 2007, 10:46:47 AM »
Any reason why you're not using generics then, if it's framework v2?

sinc

  • Guest
Re: serialize collectionBase
« Reply #8 on: November 28, 2007, 11:47:07 AM »
That code looks like it has some nasty traps possible.

That whole thing where the collection has a "parent" property, with getter and setter, but then each individual "Lite" also has a parent...  That sounds nasty to me.  What happens if someone changes the parent Lite for the collection after a bunch of Lites are added?

And I too would recommend that you use generics instead.  The old List needs to box/unbox the elements inside it every time you do something, which results in a performance hit (although it's possible the hit isn't big enough to really notice).

And out of curiosity, what is a "Lite", anyway, besides a type of beer? :-)   Looks like it has something to do with doors, but I've never heard the term...

Draftek

  • Guest
Re: serialize collectionBase
« Reply #9 on: November 28, 2007, 04:08:35 PM »
The code is merely thrown together for proto-typing at this point.

The parent object in the collection is used to set the parent of each member. I've used this method before and it works really well where you need to 'chain' children.. Think of browser nodes in a treeview control.

If somebody will throw me a 'generics' example, I'd be very interested to see it.

Thanks

Glenn R

  • Guest
Re: serialize collectionBase
« Reply #10 on: November 28, 2007, 06:14:19 PM »
Give this a run around the yard.

Cheers,
Glenn.

Glenn R

  • Guest
Re: serialize collectionBase
« Reply #11 on: November 28, 2007, 06:16:49 PM »
Whoops! Forgot the starter XML file:

Code: [Select]
<Projects>
  <Project>
    <Number>100</Number>
    <Description>First project</Description>
  </Project>
  <Project>
    <Number>101</Number>
    <Description>Second project</Description>
  </Project>
</Projects>

Place in the same folder as the dll.

Draftek

  • Guest
Re: serialize collectionBase
« Reply #12 on: November 28, 2007, 06:37:50 PM »
I'll give it a shot Glenn.

Thanks

Draftek

  • Guest
Re: serialize collectionBase
« Reply #13 on: November 28, 2007, 07:40:04 PM »
works great! I changed cLites to this:
Code: [Select]
[Serializable]
    public class cLites :List<cLite>
    {

        // constructor - when the collection is created, you need a parent lite
        // to add to all of the children created from the add method

        public cLites(cLite parent)
        {
            m_parentLite = parent;
        }
        #region private members
        // parent lite
        private cLite m_parentLite;

        #endregion

        #region public Members
        [XmlElementAttribute("parentLite", typeof(cLite))]
        public cLite ParentLite
        {
            get { return m_parentLite; }
            set { m_parentLite = value; }
        }

        #endregion

    }

works AND cut out the implementation code AND the wrapper class - Nice!

Looks like I have some reading to do...
Thanks Glenn

Glenn R

  • Guest
Re: serialize collectionBase
« Reply #14 on: November 28, 2007, 07:45:01 PM »
nurries.