Click here to Skip to main content
15,902,939 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
I create main form like this
http://image.ohozaa.com/view2/xTGvIUCRxnvUo36h[^]

Setting form
http://image.ohozaa.com/view2/xTGwbCU6vmIpqRs3[^]

Show form
http://image.ohozaa.com/view2/xTGwrzWNgMdZ39P4[^]

When I click show button in the main form(form1). The show form,I want it show the value when I insert the value and click ok button from the setting form.I can't do it
Please look at my code

main form:

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

       private void settingButton_Click(object sender, EventArgs e)
       {
           new Setting().ShowDialog();
       }

       private void showButton_Click(object sender, EventArgs e)
       {
           new Show().ShowDialog();
       }
   }


Setting form:
C#
public partial class Setting : Form
    {
        ListViewItem[] listViewAddGenderAge_ListViewItem = new ListViewItem[5];
        int checkAddClick;
        String[] gender = new String[5];
        String[] age = new String[5];

     
        
        public Setting()
        {
            InitializeComponent();
        }

        private void addButton_Click(object sender, EventArgs e)
        {
            checkAddClick = 0;
            for (int i = checkAddClick; i < checkAddClick+1; i++)
            {
                gender[i] = genderText.Text;
                age[i] = ageText.Text;

                listViewAddGenderAge_ListViewItem[i] = new ListViewItem(gender[i]);
                listViewAddGenderAge_ListViewItem[i].SubItems.Add(age[i]);
                listViewAdd.Items.Add(listViewAddGenderAge_ListViewItem[i]);
            }
            checkAddClick += 1;
        }

        private void Setting_Load(object sender, EventArgs e)
        {

        }
        Show showForm;
        private void OKButton_Click(object sender, EventArgs e)
        {
            showForm = new Show(this,gender,age);
            this.Close();
        }
    }


Show form:
C#
public partial class Show : Form
   {
       Setting settingForm;
       ListViewItem[] listViewShow_ListViewItem = new ListViewItem[5];

       public Show()
       {
           InitializeComponent();
       }

       public Show(Form callingform,String[] age,String[] gender)
       {
           age = new String[5];
           gender = new String[5];
           settingForm = callingform as Setting;
           for (int i = 0; i < 5; i++)
           {
               this.listViewShow_ListViewItem[i]=new ListViewItem(i.ToString());
               this.listViewShow_ListViewItem[i].SubItems.Add(age[i]);
               this.listViewShow_ListViewItem[i].SubItems.Add(gender[i]);
               this.listViewShow.Items.Add(this.listViewShow_ListViewItem[i]);
           }
       }

   }


thank you
Posted
Comments
BillWoodruff 10-Oct-14 15:24pm    
There are a lot of things in your code that don't make sense, and a few obvious errors. I suggest you try to add a clear statement to your question of what it is you want to achieve.

Some obvious things:

You are creating new instances of the Forms 'Show and 'Setting each time the buttons on the Main Form are pressed.

In your code for the Settings Form: you create a new instance of the 'Show Form which you never use.

Anytime you create a new instance of a Form inside a method, or in another Form, and do not keep a reference to that instance of the Form "alive," you no longer have access to it; it's garbage collected, all data is lost.
Sergey Alexandrovich Kryukov 10-Oct-14 15:33pm    
Yes... it looks like a "get back to basics" kind of thing. Hard to advise anything else...
—SA
Member 11144476 10-Oct-14 16:23pm    
If you look at my pictures,the show form and the setting form.The list view look like the same.I just want to get the value from list view in setting form that user can add the value in there,and show it in the show form like the same pattern when user click OK button in the setting form.The even will happen when user click OK button,The value in show form will be the same value in setting form.You have the other way for me? So sorry, I ask not clear .I'm foreign pepole and I'm new for C#.
BillWoodruff 10-Oct-14 17:06pm    
Sawasdee Khrup, Pom khitwah ban tee prunee, don bai, mee whelar study code kong Khun, Khrup. Ta pom mee idea khit doulet Khun dai, pom tam sangwai yu tee nee. Norn dee, fun dee, na, Khrup.

This is an interesting question to me because: to create a solution you have to work-around some of the limits of the WinForms application model. In my experience, many newcomers to WinForms .NET find those "limits" arbitrary, unexpected.

Ideally, you'd like to have the ability to have one ListView Control appear in more than Window, but that will not happen in WinForms. Yes, WinForms does allow you to move a Control from one Form to another, and it is true that the Control does not lose its data when moved, but that is not suitable for a scenario like this one which requires two ListViews be visible.

Ideally, you'd like to have one DataSet, and whenever the Data in that DataSet was modified, the two ListViews in two Forms required here would be bound to it, and update automatically. However, the WinForms ListView does not support true databinding.

Another limit of the ListView Control is that it provides no Events for adding, or deleting, a ListViewItem. And, any new ListViewItem created that needs to be added to another ListView's Item Collection must be ... cloned.

So, the challenge here is to allow creation of new Data ... a new ListViewitem ... in one Form (SettingForm), and add the new ListViewItem to the ListView shown in the second Form (Showform), and to synchronize their data content.

In the solution ... one of many possible strategies ... presented here I chose to locate the update mechanism for the second ListView in the 'ShowForm from a method defined in the MainForm; that required injecting a reference to a named executable method in the MainForm into the public variable of Type 'Action (a form of Delegate) defined in the 'SettingForm.

Note that a delegate of Type 'Action is multi-cast delegate, but we are not using it that way here: we have assigned to it rather than subscribed to it using +=.

The update solution also required that the MainForm have a reference to the ListView in the 'ShowForm. This is implemented by having a Public Property of Type 'ListView in the 'ShowForm which is initialized in the constructor of the Class.

I chose to create FormClosing EventHandlers for both SettingForm and ShowForm that instead of closing the Forms hides them in order to prevent data loss, and possible complications if the user at run-time closed the Forms. An obvious alternative would be to hide the CloseBox on those Forms, and handle that with other code.
// MainForm
using System;
using System.Windows.Forms;

namespace SynchronizedLists
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private SettingForm SettingForm = new SettingForm();

        private ShowForm ShowForm = new ShowForm();
        private ListView PointerToShowFormListView;

        private void MainForm_Load(object sender, EventArgs e)
        {
            // inject a method into the public Action variable in the Setting Form
            SettingForm.UpdateShowFormListView = UpdateShowFormListView;

            // get a reference to the ListView on the Show Form
            PointerToShowFormListView = ShowForm.ShowFormListView;
        }

        // this method will be invoked by code in the Setting Form
        private void UpdateShowFormListView(ListViewItem newListViewItem)
        {
            // copy the new ListItem on the Setting Form
            // and add it to the ListView on the Show Form
            PointerToShowFormListView.Items.Add(newListViewItem.Clone() as ListViewItem);
        }

        private void btnShowSettingForm_Click(object sender, EventArgs e)
        {
            if (! SettingForm.Visible) SettingForm.Show();
        }

        private void btnShowShowForm_Click(object sender, EventArgs e)
        {
            if (! ShowForm.Visible) ShowForm.Show();
        }
    }
}

// SettingForm
using System;
using System.Windows.Forms;

namespace SynchronizedLists
{
    public partial class SettingForm : Form
    {
        public SettingForm()
        {
            InitializeComponent();
        }

        // see notes: the Main Form will inject a pointer
        // to an executable method defined in the Main Form
        // into this variable
        public Action<listviewitem> UpdateShowFormListView;

        private void btnOkay_Click(object sender, EventArgs e)
        {
            // create the new item
            var newItem = new ListViewItem(tBxGender.Text);
            newItem.SubItems.Add(tBxAge.Text);

            // add the new item to the ListView in this Form
            // which is named 'settingListView
            settingListView.Items.Add(newItem);

            // invoke the method defined in MainForm 
            // that will update the ListView in the 'ShowForm
            UpdateShowFormListView(newItem);
        }

        // prevent the Form from being closed and losing the data
        private void SettingForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.Hide();
            e.Cancel = true;
        }
    }
}

// ShowForm
using System;
using System.Windows.Forms;

namespace SynchronizedLists
{
    public partial class ShowForm : Form
    {
        public ShowForm()
        {
            InitializeComponent();

            // get the reference to the ListView on this Form
            ShowFormListView = this.listView1;
        }

        // make this Form's ListView available to the Main Form
        public ListView ShowFormListView { private set; get; }

        // prevent the Form from being closed and losing the data
        private void ShowForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.Hide();
            e.Cancel = true;
        }
    }
}
 
Share this answer
 
v4
Comments
Sergey Alexandrovich Kryukov 11-Oct-14 21:49pm    
Good explanation and effort. However, I voted 4, not 5, due some inaccurate points I can see.

First, I again want to warn against setting not so good sample of using auto-generated names which violate Microsoft naming conventions. In particular, the use of '_' is not recommended. I really think that all names should be renamed using the refactoring engine. Also, you should better show all += operators on delegate instances, not relying on assumption that the naming suggests that the method are used as the handler, added to some invocation lists. Quite a small thing but...

More essential thing is: the type Action cannot be called "multi-cast delegate". There are two different kinds of types. You create a delegate type. This is one thing. Then you use it to declare a delegate instance. When you add first handler to a delegate instance, it becomes and object of some type. Let me call it "type of the delegate instance". Now, the trick is: the "type of the delegate instance" (which is actually a class, a single or multi-cast delegate) and the "delegate type" are completely different types. The "type of the delegate instance" can be multi-cast, by "delegate type" cannot; it is absolutely agnostic it its possible use as for a delegate instance.

This aspect of .NET is tricky for undertanding. I described part of it here: Dynamic Method Dispatcher; 4.1 On the Nature of Delegate Instance.

—SA
BillWoodruff 12-Oct-14 1:10am    
Please see this thread (which I started) here:

http://www.codeproject.com/Messages/4919609/using-naked-Action-Func-as-EventHandlers-Csharp-la.aspx

For a discussion of Action and Func as multi-cast delegates. I'll read your article with interest.
Please see my recent answer: How to passing data from Event to other form[^].

—SA
 
Share this answer
 
Comments
BillWoodruff 10-Oct-14 17:09pm    
The OP is certainly going to need to understand this, now ... or later. I've seen several beginning students kind of stumble on the fact that you can't somehow use the same Control ... in this case a ListView ... in different Forms, kind of just hop-skip-jumping over the need to pass data. I don't think it's unreasonable for someone to assume you can :)
Sergey Alexandrovich Kryukov 10-Oct-14 17:52pm    
Interestingly, WPF, unlike Forms, introduce special protection against adding to UIElement references in two different nodes of a logical tree.
—SA
BillWoodruff 10-Oct-14 23:19pm    
The "evil thing" is that you can actually relocate a WinForms Control from Form to Form, very simply, and it maintains its state/data. But, this is something I instinctively avoid showing anyone how to do.

While in this case the OP shows two Forms using ShowDialog, the base Form is, evidently persistent, and the ListView would "vanish" from the base Form were it relocated to another Form shown modally.
Sergey Alexandrovich Kryukov 10-Oct-14 23:33pm    
I agree. However, it could be useful for some very specific applications. First thing I could imaging: your own form designer.
—SA
BillWoodruff 10-Oct-14 23:39pm    
That's an interesting idea, but you do have the limitation that a given Control, like our bodies, can only be in one place at one time :)

What if WinForms had a top-level Control.Clone method one could use ? That would be different.

Thinking in MVC terms ... which is so rarely done with WinForms ... and the nature of WinForms' structure certainly doesn't foster that ... one immediately can "visualize" one configuration/data model that keeps three different Controls of the same Type on different Forms synchronized.

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