Can't save object UserData to 3dm file

Hello,

I’m trying to attach some information to RhinoObject UserData and I want to save the information to 3dm file when saving the model.

So far I had success writing and reading the information to the object, but for some reason the information does not save in the model when saving, hence it’s not possible to retrieve the information after the reopening the model.

My code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Newtonsoft.Json;

namespace IFC_MANAGER
{
    public class IFC_Data : Rhino.DocObjects.Custom.UserData
    {
        public List<Dictionary<string, string>> dataList = new List<Dictionary<string, string>>();

        // Your UserData class must have a public parameterless constructor
        public IFC_Data() { }

        public IFC_Data(Dictionary<string, string> data)
        {
            dataList.Add(data);
        }

        public override string Description
        {
            get { return "Some Custom Properties"; }
        }

        public void AddData(Dictionary<string, string> data)
        {
            dataList.Add(data);
        }

        public override string ToString()
        {
            string result = string.Empty;

            foreach (Dictionary<string, string> dict in dataList)
            {
                foreach (KeyValuePair<string, string> kvp in dict)
                {
                    result += string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
                    result += ".\n";
                }
            }

            return result;
        }

        protected override void OnDuplicate(Rhino.DocObjects.Custom.UserData source)
        {
            IFC_Data src = source as IFC_Data;

            if (src != null)
            {
                dataList = src.dataList;
            }
        }

        // return true if you have information to save
        public override bool ShouldWrite
        {
            get
            {
                // make up some rule as to if this should be saved in the 3dm file
                if (this.dataList.Count > 0)
                {
                    return true;
                }

                return false;
            }
        }

        protected override bool Read(Rhino.FileIO.BinaryArchiveReader archive)
        {
            Rhino.Collections.ArchivableDictionary dict = archive.ReadDictionary();

            if (dict.ContainsKey("dataList"))
            {
                MessageBox.Show((string)dict["dataList"]);
                dataList = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>((string)dict["dataList"]);
            }

            return true;
        }

        protected override bool Write(Rhino.FileIO.BinaryArchiveWriter archive)
        {
            try
            {
                var dataListString = JsonConvert.SerializeObject(this.dataList);

                var dict = new Rhino.Collections.ArchivableDictionary(1, "IFC_Data");
                dict.Set("dataList", dataListString);
                archive.WriteDictionary(dict);
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

            return true;
        }
    }
}

Hi @WinG,

I have not fully evaluated your code. But I do notice that your class doesn’t have a GUID attribute. You need to do this:

[System.Runtime.InteropServices.Guid("YOUR_GUID_GOES_HERE")]
public class IFC_Data : Rhino.DocObjects.Custom.UserData
{

– Dale

1 Like

Thank you very much Dale, that solved the issue for me :slight_smile: