views:

59

answers:

4

Although there are some similar questions I’m having difficulties finding an answer on how to receive data in my form from a class.

I have been trying to read about instantiation and its actually one of the few things that does make sense to me :) but if I were to instantiate my form, would I not have two form objects?

To simplify things, lets say I have a some data in Class1 and I would like to pass a string into a label on Form1. Is it legal to instantiate another form1? When trying to do so it looks like I can then access label1.Text but the label isn’t updating. The only thing I can think of is that the form needs to be redrawn or there is some threading issue that I’m unaware of.

Any insight you could provide would be greatly appreciated.

EDIT: Added some code to help

class Class1
{
    public int number { get; set; }

    public void Counter()
    {
        for (int i = 0; i < 10; i++)
        {
            number = i;
            System.Threading.Thread.Sleep(5000);
        }
    }
}

and the form:

    Class1 myClass = new Class1();

    public Form1()
    {
        InitializeComponent();
        label1.Text = myClass.number.ToString();
    }
+3  A: 

NO,

I think your form needs to access a reference to Class1 to use the data available in that, and not the other way around.

VERY seldomly a data class should instanciate a display form to display what it has to offer.

If the class is a data access layer of singleton, the form should reference that class, and not the other way around.

astander
+1  A: 

There's no reason why you can't have multiple instances of a form, but in this case you want to pass the Class1 instance to the form you have. The easiest way is to add a property to Form1 and have that update the label text:

public class Form1 : Form
{
    public Class1 Data
    {
        set
        {
            this.label.Text = value.LabelText;
        }
    }
}
Lee
A: 

Events and delegates are what you want to use here. Since you tagged this as beginner, I will leave the implementation as an exercise :), but here is the general idea:

  1. Declare an event/delegate pair in your data class.
  2. Create a method in your form to bind to the event.
  3. When "something" happens in your data class, fire the event
  4. The form's method will be invoked to handle the event and can update widgets appropriately

Good luck.

cdkMoose
+1  A: 

Based on the comments in your original post, here are a few ways to do it: (this code is based on a Winform app in VS2010, there is 1 form, with a Label named "ValueLabel", a textbox named "NewValueTextBox", and a button.

Also, there is a class "MyClass" that represents the class with the changes that you want to publish.

Here is the code for the class. Note that I implement INotifyPropertyChanged and I have an event. You don't have to implement INotifyPropertyChanged, and I have an event that I raise whenever the property changes.

You should be able to run the form, type something into the textbox, click the button, and see the value of the label change.


    public class MyClass: System.ComponentModel.INotifyPropertyChanged
    {
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        public string AValue
        {
            get
            {
                return this._AValue;
            }
            set
            {
                if (value != this._AValue)
                {
                    this._AValue = value;
                    this.OnPropertyChanged("AValue");
                }
            }
        }
        private string _AValue;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if(this.PropertyChanged != null)
                this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }

Example 1: simple databinding between the label and the value: So this time, we will just bind the label to an instance of your class. We have a textbox and button that you can use to change the value of the property in MyClass. When it changes, the databinding will cause the label to be update automatically:

NOTE: Make sure to hook up Form1_Load as the load event for hte form, and UpdateValueButton_Click as the click handler for the button, or nothing will work!


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private MyClass TheClass;

        private void Form1_Load(object sender, EventArgs e)
        {
            this.TheClass = new MyClass();
            this.ValueLabel.DataBindings.Add("Text", this.TheClass, "AValue");
        }

        private void UpdateValueButton_Click(object sender, EventArgs e)
        {
            // simulate a modification to the value of the class
            this.TheClass.AValue = this.NewValueTextBox.Text;
        }
    }

Example 2 Now, lets bind the value of class directly to the textbox. We've commented out the code in the button click hander, and we have bound both the textbox and the label to the object value. Now if you just tab away from the textbox, you will see your changes...


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private MyClass TheClass;

        private void Form1_Load(object sender, EventArgs e)
        {
            this.TheClass = new MyClass();
            // bind the Text property on the label to the AValue property on the object instance.
            this.ValueLabel.DataBindings.Add("Text", this.TheClass, "AValue");
            // bind the textbox to the same value...
            this.NewValueTextBox.DataBindings.Add("Text", this.TheClass, "AValue");
        }

        private void UpdateValueButton_Click(object sender, EventArgs e)
        {
            //// simulate a modification to the value of the class
            //this.TheClass.AValue = this.NewValueTextBox.Text;
        }


Example 3 In this example, we won't use databinding at all. Instead, we will hook the property change event on MyClass and update manually.

Note, in real life, you might have a more specific event than Property changed -- you might have an AValue changed that is only raised when that property changes.


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private MyClass TheClass;

        private void Form1_Load(object sender, EventArgs e)
        {
            this.TheClass = new MyClass();
            this.TheClass.PropertyChanged += this.TheClass_PropertyChanged;
        }

        void TheClass_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "AValue")
                this.ValueLabel.Text = this.TheClass.AValue;
        }

        private void UpdateValueButton_Click(object sender, EventArgs e)
        {
            // simulate a modification to the value of the class
            this.TheClass.AValue = this.NewValueTextBox.Text;
        }
    }

JMarsch