Click here to Skip to main content
15,867,453 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
I have built a software which retrieve the weight from digital scale and output it in a label in WinForms. Every time the weight changes in the scale it is also automatically updated in the label. Successfully I made it.

This is my code:


C#
public partial class Form1 : Form
{
    private SerialPort port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);

    public Form1()
    {
        InitializeComponent();

        port.DtrEnable = true;
        port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        port.Open();
    }

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            this.Invoke(new EventHandler(DoUpdate));
        }
        catch (Exception ex)
        {

        }
    }

    private void DoUpdate(object s, EventArgs e)
    {
        try
        {
            label1.Text = port.ReadLine();
        }
        catch (Exception ex)
        {
            label1.Text = ex.ToString();
        }
    }
}



Now, my boss asked me to implement this code in a .DLL file (Class Library). He just wants to add as a reference, call the class and it returns the weight and also it updates automatically.
He just wants to make a simple call on Page Load like this sample:

C#
Scale sc = new Scale();
label1.text = sc.weight();



I can successfully return the weight but it does not updated automatically via the Class Library and this is the code I am using in my Class Library (.DLL file):

C#
public class Scale
{
    SerialPort port;

    public string weight()
    {
        try
        {
            port = new SerialPort(com, 9600, Parity.None, 8, StopBits.One);

            if (port.IsOpen == false)
            {
                port.Open();
            }

            port.DtrEnable = true;

            return port.ReadLine();;
        }
        catch(Exception ex)
        {
            return "";
        }
    }
}



I hope I was explained clearly. Any help with the code?
Thanks in advance.
Posted

Add an event to your Scale class - and the class signals the event each time the weight changes.
You then add a handler to your presentation code which updates the label:
C#
Scale sc = new Scale();
sc.WeightChanged += Scale_WeightChanged;
...
void Scale_WeightChanged(object sender, EventArgs e)
    {
    Scale sc = sender as Scale;
    if (sc != null)
         {
         label1.text = sc.weight();
         }
    }

Adding an event is easy: A Simple Code Snippet to Add an Event[^] shows the code and a way to make it easier to add them in future.
 
Share this answer
 
Comments
Andy Lanng 21-May-15 4:51am    
Ha! My solution is the exact other half of this! (but I send the weight in the event)

We should work together, OG. ^_^
Expose an event from your dll. Every time the data SerialDataReceivedEventHandler is called, invoke the event:

C#
public class Scale : IDisposable //This will mean that the Dispose method is called when the invokation is cleaned up
    {
        //It's ok to kep this up.  We'll close it when this invokation is cleaned up
        SerialPort port = new SerialPort("com", 9600, Parity.None, 8, StopBits.One);

        public Scale()
        {
            port.DtrEnable = true;
            port.DataReceived += OnWeightChanged;
        }

        //This dictates what the event will look like.  It's often declared outside the class.
        public delegate void ScaleWeightChangeHandler(object sender, string weight);

        //Out event.  This is what is exposed to the calling code (i.e. scale.WeightChanged += new ScaleWeightChangeHandler(fubar);
        public event ScaleWeightChangeHandler WeightChanged;

        //We call this to fire the event
        private void OnWeightChanged(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
        {
            if (WeightChanged != null)
                WeightChanged(sender, Weight());
        }

        //The Weight can still be retrieved manually (especially the first time)
        public string Weight()
        {
            try
            {
                if (port.IsOpen == false)
                {
                    port.Open();
                }

                port.DtrEnable = true;

                return port.ReadLine(); 
            }
            catch (Exception ex)
            {
                return "";
            }
        }

        //Cleanup the port on Dispose.  This is the benefit of IDisposable

        #region Corrected from comments below

        public void Dispose()
        {
            Dispose(true);
        }
 
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                port.DataReceived -= new SerialDataReceivedEventHandler(getPesha);
            }
 
            if (port != null)
            {
                if (port.IsOpen)
                {
                    port.Close();
                }
 
                port.Dispose();
            }
        }
        #endregion
    }


(Bet I'm not the first solution response, but it's gotta be the best ^_^ )

Hope that helps
Andy


EDIT: corrected the Dispose methods from comments below
 
Share this answer
 
v2
Comments
AldoBlack 21-May-15 6:03am    
Wow. Thanks. I really appreciate it. It seems it it working but when the weight changes it gives me error on Weight Class.
This is how I call it from WinForms:

Scale t = new Scale();

public Form1()
{
InitializeComponent();

t.WeightChanged += new test.ScaleWeightChangeHandler(fubar);
label1.Text = t.Weight();
}

private void fubar(object sender, string weight)
{
label1.Text = t.Weight();
t.dispose();
}

Any idea why?
Andy Lanng 21-May-15 6:08am    
No idea without knowing what the error is.

Remember that the event will occur in a separate thread. Use the Invoke from your original post to get back to the form thread.

(and don't call your method fubar :Þ )
AldoBlack 21-May-15 6:17am    
Yeap. It works now. THAAAANK YOU. :D I hope you will be here if I need you in a near future. :P :)
Hahahahaha and No, I have named my method in my native language but I post here not to distract. :D :)
Andy Lanng 21-May-15 6:20am    
cool - I figured :)

I'm usually around. I don't always produce such full code. I like people to figure stuff out on their own (i.e. the invoke here).

You've done me proud in figuring out the code around my solution. Keep up the good work ^_^
AldoBlack 21-May-15 6:31am    
Thank you, You too. :D :D :D

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900