C# numericUpDown & button Issue

Q : When I type numbers inside numericUpDown slides and click “Apply” button, the numbers are imported inside the grasshopper parameter, “That’s a great news !!”. However, Whenever I saved the grasshopper file, closed the rhino file, and then reopened the rhino and grasshopper file, the numericUpDown values, and the values inside the grasshopper parameter are reset.

But I want to persist all these numbers after I click “Apply” button and save the grasshopper file.

How can I solve this problem??

Here are the images and codes.


using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Grasshopper.GUI;
using Grasshopper.Kernel;
using Grasshopper.GUI.Canvas;
using Grasshopper.Kernel.Attributes;

namespace RFD
{
public class Toolinfo : GH_Component
{
#region constructor
///


/// Initializes a new instance of the MyComponent1 class.
///
///
///

public Toolinfo()
: base(“Toolinfo”, “Toolinfo”,
“This Parameter gets informations of the tool. Please read the instruction before using this parameter.”,
“RFD”, “2.Toolinfo”)
{
ToolValue = 0;
XValue = 0;
YValue = 0;
ZValue = 0;
AValue = 0;
BValue = 0;
CValue = 0;
}

    /// <summary>
    /// Registers all the input parameters for this component.
    /// </summary>
    protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
    {

    }

    /// <summary>
    /// Registers all the output parameters for this component.
    /// </summary>
    protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
    {
        pManager.AddNumberParameter("Toolinfo", "Toolinfo", "Toolinfo", GH_ParamAccess.list);

    }
    #endregion

    #region attributes
    /////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////
    ////////<Winidow Form Start>/////////////////////////////

    public override void CreateAttributes()
    {
        m_attributes = new MySpecialComponentAttributes(this);
    }

    public class MySpecialComponentAttributes : GH_ComponentAttributes
    {
        public MySpecialComponentAttributes(IGH_Component component) : base(component) { }

        public override GH_ObjectResponse RespondToMouseDoubleClick(GH_Canvas sender, GH_CanvasMouseEvent e)
        {

            (Owner as Toolinfo)?.DisplayForm();

            return GH_ObjectResponse.Handled;

        }

    }

    #endregion

    #region UI overrides

    RFD.Form1 _form;

    public void DisplayForm()
    {

        // Don't show the form more than once per component.
        //if (_form != null)
        //  return;

        if (_form != null)
        { return; }

        _form = new Form1();



        _form.FormClosed += OnFormClosed;


        _form.button1.Click += button1_Click;


        /// ""Use these line if you want to use TrackBar as a realtime input""
        ///
        /// _form.trackBar1.ValueChanged += trackBar1_ValueChanged;
        ///

        GH_WindowsFormUtil.CenterFormOnCursor(_form, true);
        _form.Show(Grasshopper.Instances.DocumentEditor);

    }

    private void button1_Click(object sender, EventArgs e)
    {

        Button button = sender as Button;

        ToolValue = Math.Round((double)_form.numericUpDown1.Value);
        XValue = Math.Round((double)_form.numericUpDown2.Value, 1);
        YValue = Math.Round((double)_form.numericUpDown3.Value, 1);
        ZValue = Math.Round((double)_form.numericUpDown4.Value, 1);
        AValue = Math.Round((double)_form.numericUpDown5.Value, 1);
        BValue = Math.Round((double)_form.numericUpDown6.Value, 1);
        CValue = Math.Round((double)_form.numericUpDown7.Value, 1);


        ExpireSolution(true);
    }

    /// ""Use these line if you want to use TrackBar as a realtime input""
    /// 
    /// 
    /// private void trackBar1_ValueChanged(object sender, EventArgs e)
    /// {

    /// TrackBar trackBar = sender as TrackBar;
    ///   if (trackBar != null)
    ///    {
    ///     Value = trackBar.Value;
    ///     ExpireSolution(true);
    ///    }
    /// }
    ///


    private void OnFormClosed(object sender, FormClosedEventArgs formClosedEventArgs)
    {
        _form = null;
    }

    /// <summary>
    /// Override this function if you want to insert some custom menu items in your derived Component class.
    /// Items will be added between List Matching items and parameter menus.
    /// </summary>
    protected override void AppendAdditionalComponentMenuItems(ToolStripDropDown menu)
    {
        Menu_AppendItem(menu, "Show UI", ShowUiClicked, null, true, false);
    }
    private void ShowUiClicked(object sender, EventArgs e)
    {
        DisplayForm();
    }

    ////////<Winidow Form End>///////////////////////////////
    /////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////
    #endregion

    /// <summary>
    /// This is the method that actually does the work.
    /// </summary>
    /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>

    protected override void SolveInstance(IGH_DataAccess DA)
    {



        double ToolNumber = Math.Round(ToolValue);
        double Xmove = Math.Round(XValue, 1);
        double Ymove = Math.Round(YValue, 1);
        double Zmove = Math.Round(ZValue, 1);
        double Aangle = Math.Round(AValue, 1);
        double Bangle = Math.Round(BValue, 1);
        double Cangle = Math.Round(CValue, 1);




        List<double> toolInfo = new List<double>();

        toolInfo.Add(Xmove);
        toolInfo.Add(Ymove);
        toolInfo.Add(Zmove);
        toolInfo.Add(Aangle);
        toolInfo.Add(Bangle);
        toolInfo.Add(Cangle);
        toolInfo.Add(ToolNumber);

        DA.SetDataList("Toolinfo", toolInfo);
    }


    public double ToolValue { get; set; }
    public double XValue { get; set; }
    public double YValue { get; set; }
    public double ZValue { get; set; }
    public double AValue { get; set; }
    public double BValue { get; set; }
    public double CValue { get; set; }


    /// <summary>
    /// Provides an Icon for the component.
    /// </summary>
    protected override System.Drawing.Bitmap Icon
    {
        get
        {
            return RFD.Properties.Resources.ICON_8_ToolInfo;
        }
    }

    /// <summary>
    /// Gets the unique ID for this component. Do not change this ID after release.
    /// </summary>
    public override Guid ComponentGuid
    {
        get { return new Guid("b72bb830-a0b4-4d53-98a2-81834631d33c"); }
    }
}

}

Anything you want to persist between sessions of a grasshopper document needs to serialize and deserialize the data it cares about inside the component class. You can override the Read and Write methods on the component to do this.

1 Like

Thank you for your advice.
Can you please also attach a simple example file for it ??
I tried to search a reference of how to override Read and Write methods.
But, I couldn’t find one.

Here’s an example from one of my plug-ins. I’m storing a boolean value called IncludeNullAndEmptyProperties. https://github.com/andrewheumann/jSwan/blob/cb736b8e7de8c07042fefeb621d6ad88503b91d8/jSwan/Serialize.cs#L128

1 Like

Wow. I really appreciate your sharing.

I will try your solution as soon as possible.

I solved the problem.

Thank you for your help.