Windows forms передача данных между формами

Как передавать данные между формами C#, .NET 4.x Решение и ответ на вопрос 540379

.NET 4.x

Как передавать данные между формами

06.04.2012, 05:44. Показов 46733. Ответов 4


Hi!
Написал по сабжу статью (первоначально — себе в блог), но решил выложить тут. Полезнее будет, может кому и пригодится.

В процессе изучения C# вообще и WinForms в частности, у многих неофитов возникает вполне закономерный вопрос — а как передавать данные (в общем — объекты, но для начала хотя бы просто строки/числа). Кроме того, данные порой нужно передавать не только из основной формы в дочернюю, но и в обратном направлении. Для каждого из этих действий есть несколько способов реализации, и применение каждого из них зависит от контекста задачи, а также — от стиля и опыта программиста. Как правило, программисты выбирают себе несколько способов, которые используют в своих проектах. Я постарался в данной статье привести все известные мне способы, а так же их комбинации. Статья логически разделена на две части — прямая передача данных (из основной формы в дочернюю) и обратная.

Задача 1: Передать текстовую строку из основной формы в дочернюю
Реализация 1: Передать через конструктор дочерней формы
Самый простой способ. Класс дочерней формы конструируется таким образом, чтобы конструктор (или одна из его перегрузок) класса принимал в качестве аргумента или аргументов некие данные. Способ удобен тем, что в дочернюю форму можно передать практически неограниченное количество данных фактически любого типа. Неудобен он тем, что класс дочерней формы в этом случае становится слишком узкоспециализированным. При разработке небольших проектов это не почувствуется, но если вы возьметесь за масштабное модульное бизнес-приложение, сразу поймете всю узкость данного подхода. Но, тем не менее, не рассмотреть его было бы несправедливо.
Листинг 1.1.1. Основная форма:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    //Основная форма
    public partial class MasterForm : Form
    {
        public MasterForm()
        {
            InitializeComponent();
        }
 
        //Обрабатываем событие Click на кнопке
        private void SendB_Click(object sender, EventArgs e)
        {
            //Создаем экземпляр дочерней формы. В качестве аргумента конструктора указываем значение свойства Text текстбокса DataTB
            SlaveForm SF = new SlaveForm(DataTB.Text);
 
            //Показываем форму. В данном конкретном случае все равно как показывать: с помощью метода Show() либо ShowDialog()
            SF.Show();
        }
    }

Листинг 1.1.2. Дочерняя форма:

C#
1
2
3
4
5
6
7
8
9
10
    //Дочерняя форма
    public partial class SlaveForm : Form
    {
        public SlaveForm(String Data)
        {
            InitializeComponent();
            //Полученные в качестве аргумента данные напрямую пишем в свойство Text текстбокса
            InboxTB.Text = Data;
        }
    }

Думаю, все понятно и без дальнейших комментариев :-)

Реализация 2: Передать через public-переменную или свойство класса дочерней формы.
Способ чуть посложнее. Потребуется создать в классе дочерней формы дополнительную переменную или свойство (в данном случае — это не важно), и обработать событие Load дочерней формы.
Листинг 1.2.1. Основная форма:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    //Основная форма
    public partial class MasterForm : Form
    {
        public MasterForm()
        {
            InitializeComponent();
        }
 
        private void SendB_Click(object sender, EventArgs e)
        {
            //Создаем экземпляр формы
            SlaveForm SF = new SlaveForm();
 
            //Пишем в переменную InboxData данные.
            //ВНИМАНИЕ! Сначала нужно записать данные в переменную, а затем вызывать метод загрузки данных (Show()). 
            //В противном случае мы не получим данные в дочерней форме
            SF.InboxData = DataTB.Text;
 
            //Грузим дочернюю форму
            SF.Show();
        }
    }

Листинг 1.2.2. Дочерняя форма:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    //Дочерняя форма
    public partial class SlaveForm : Form
    {
        //Создаем переменную, доступную любому классу в пределах проекта
        public String InboxData = String.Empty;
        public SlaveForm()
        {
            InitializeComponent();
        }
 
        //Обрабатываем событие Load (загрузку формы), чтобы поместить полученный в переменную InboxData данные
        private void SlaveForm_Load(object sender, EventArgs e)
        {
            InboxTB.Text = InboxData;
        }
    }

Реализация 3: Передача данных через свойство/переменную статического класса.
Суть способа в следующем: использовать для временного буфера свойство или переменную статического класса. Данный способ несколько более универсальный. Хотя бы тем, что он не требует специализации класса дочерней формы, т.е. нам не придется добавлять в класс дочерней формы дополнительные свойства или переменные. Только обработать событие Load формы.

Листинг 1.3.1. Статический класс:

C#
1
2
3
4
5
6
//Статический класс, одна из переменных которого выступит в качестве буфера для данных
    public static class StaticData
    {
        //Буфер данных
        public static String DataBuffer = String.Empty;
    }

Листинг 1.3.2. Основная форма:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    //Основная форма
    public partial class MasterForm : Form
    {
        public MasterForm()
        {
            InitializeComponent();
        }
 
        private void SendB_Click(object sender, EventArgs e)
        {
            //При клике на кнопке обработчик события Click пишет строку из текстбокса в переменную статического класса,...
            StaticData.DataBuffer = DataTB.Text;
 
            //...создает экземпляр дочерней формы и отображает ее
            SlaveForm SF = new SlaveForm();
            SF.Show();
 
            //Опять же, для того, чтобы данные успешно отобразились в дочерней форме, запись их в переменную 
            //статического класса необходимо делать ДО вызова формы
        }
    }

Листинг 1.3.3. Дочерняя форма:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    //Дочерняя форма
    public partial class SlaveForm : Form
    {
        public SlaveForm()
        {
            InitializeComponent();
        }
 
        private void SlaveForm_Load(object sender, EventArgs e)
        {
            //При возникновении события Load обработчик считывает данные из статического буфера и отображает их в текстбоксе
            InboxTB.Text = StaticData.DataBuffer;
        }
    }

Реализация 4: Запись данных напрямую в TextBox дочерней формы через обработку события Load анонимным методом.
Не самый лучший вариант, попахивающий карри и индийскими слонами, но для полноты картины продемонстрирую и его. Суть способа в том, что в основной форме при обработке события Click на кнопке с помощью анонимного метода подписаться на событие Load дочерней формы и задать для этого события обработчик. А в обработчике уже производить присвоение свойству Text текстбокса дочерней формы каких-либо значений. Текстбоксу дочерней формы в этом случае должен быть присвоен модификатор public.
Листинг 1.4.1 Основная форма:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    //Основная форма
    public partial class MasterForm : Form
    {
        public MasterForm()
        {
            InitializeComponent();
        }
 
        //Обработчик события Click
        private void SendB_Click(object sender, EventArgs e)
        {
            //Создаем экземпляр формы
            SlaveForm SF = new SlaveForm();
 
            //С помощью анонимного метода обрабатываем событие Load дочерней формы в основной форме
            SF.Load += (sender1, e1) =>
                {
                    //В свойство Text текстбокса на дочерней форме пишем данные из свойста Text текстбокса основной формы
                    SF.InboxTB.Text = DataTB.Text;
                };
 
            //После того, как подписались на событие Load, загружаем форму
            SF.Show();
        }
    }

Листинг 1.4.2. Дочерняя форма:

C#
1
2
3
4
5
6
7
8
9
    //Класс дочерней формы. Тут мы ничего не делаем, за исключением того, что меняем модификатор доступа для 
    //текстбокса с private на public в свойствах этого текстбокса
    public partial class SlaveForm : Form
    {
        public SlaveForm()
        {
            InitializeComponent();
        }
    }

Задача 2. Передать данные из дочерней формы в основную
Реализация 1. Через статический класс. Тут, в общем то, все достаточно просто и похоже на подобную реализацию выше. Но есть и пара нюансов.
Поскольку по умолчанию основная форма «не знает», когда из дочерней в переменную статического класса будет записано значение, встает проблема — обновить текстбокс основной формы именно тогда, когда в статический класс будут внесены данные. В самом первом приближении это возможно при выполнении следующего условия — дочерняя форма открыта как диалог (т.е. управление передается на дочернюю форму при ее закрытии), а обновление текстбокса основной формы происходит после метода открытия дочерней формы.
Листинг 2.1.1. Статический класс

C#
1
2
3
4
5
6
//Статический класс
    public static class StaticData
    {
        //Статическая переменная, выступающая как буфер данных
        public static String DataBuffer = String.Empty;
    }

Листинг 2.1.2. Основная форма

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Основная форма
    public partial class MasterForm : Form
    {
        public MasterForm()
        {
            InitializeComponent();
        }
 
        //Вызов дочерней формы как диалога
        private void CallB_Click(object sender, EventArgs e)
        {
            SlaveForm SF = new SlaveForm();
            SF.ShowDialog();
            //Обновление текстбокса после закрытия дочерней формы
            DataTB.Text = StaticData.DataBuffer;
        }
    }

Листинг 2.1.3. Дочерняя форма

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Дочерняя форма
    public partial class SlaveForm : Form
    {
        public SlaveForm()
        {
            InitializeComponent();
        }
 
        private void SendB_Click(object sender, EventArgs e)
        {
            //По клику заполняем статическую переменную 
            StaticData.DataBuffer = OutboxTB.Text;
        }
    }

Реализация 2. Через событие закрытия окна.
При вызове дочерней формы мы можем с помощью анонимного метода подписаться на события вызываемой формы. Например, если мы подпишемся на событие закрытия окна, то сможем выполнить некие действия, когда дочерняя форма инициирует это событие (т.е. начнет закрываться).

Листинг 2.2.1. Основная форма

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    //Основная форма
    public partial class MasterForm : Form
    {
        public MasterForm()
        {
            InitializeComponent();
        }
 
        //Открываем дочернюю форму и подписываемся на ее события
        private void CallB_Click(object sender, EventArgs e)
        {
            //Создаем экземпляр формы
            SlaveForm SF = new SlaveForm();
 
            //Создаем анонимный метод - обработчик события FormClosing дочерней формы (возникающего перед закрытием)
            //Подписаться на событие необходимо до открытия дочерней формы
            //Использовать событие FormClosed не стоит, так как оно возникает уже после закрытия формы, когда все переменные формы уже уничтожены
            SF.FormClosing += (sender1, e1) =>
                {
                    //Обновляем текстбокс основной формы
                    DataTB.Text = SF.DataBuffer;
                };
 
            //Открывает форму на просмотр
            SF.Show();
        }
    }

Листинг 2.2.2. Дочерняя форма

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    //Дочерняя форма
    public partial class SlaveForm : Form
    {
        //Переменная, выполняющая роль буфера для данных
        //Переменная должна быть public, иначе мы не получим к ней доступ из основной формы
        public String DataBuffer = String.Empty;
        public SlaveForm()
        {
            InitializeComponent();
        }
 
        //Обрабатываем клик по кнопке
        private void SendB_Click(object sender, EventArgs e)
        {
            //Локальная переменная получает значение из текстбокса
            DataBuffer = OutboxTB.Text;
        }
    }

Кроме событий формы, можно подписаться на события любых public-компонентов. Но не рекомендую этого делать — это, конечно, легко и просто, но… некрасиво, что ли.

Реализация 3. Через события статического класса.
Опять задействуем посредника в виде статического класса. Однако применим на этот раз иной подход. В основной форме подпишемся на событие ValueChanged статического свойства DataBuffer. Но, поскольку свойство это «из коробки» не имеет подобных событий, его придется создать.

Листинг 2.3.1. Статический класс

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    //Статический класс
    public static class StaticData
    {
        //Описание делегата - обработчика события
        public delegate void ValueChangedEventHandler(object sender, EventArgs e);
 
        //Событие 
        public static event ValueChangedEventHandler ValueChanged;
 
        //Изолированная переменная - хранилище данных, передаваемых в свойство DataBuffer
        private static String dataBuffer = String.Empty;
 
        //Свойство DataBuffer
        public static String DataBuffer
        {
            get
            {
                return dataBuffer;
            }
            set
            {
                dataBuffer = value;
 
                //При изменении данных свойства вызывается событие ValueChanged
                ValueChanged(null, EventArgs.Empty);
            }
        }
    }

Листинг 2.3.2. Основная форма

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    //Основная форма
    public partial class MasterForm : Form
    {
        public MasterForm()
        {
            InitializeComponent();
        }
 
        //Обработка клика по кнопке
        private void CallB_Click(object sender, EventArgs e)
        {
            //Подписываемся на событие ValueChanged статического класса
            StaticData.ValueChanged += (sender1, e1) =>
                {
                    DataTB.Text = StaticData.DataBuffer;
                };
 
            //Создаем экземпляр формы
            SlaveForm SF = new SlaveForm();
 
            //Вызываем форму
            SF.Show();
        }
    }

Листинг 2.3.3. Дочерняя форма

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    //Дочерняя форма
    public partial class SlaveForm : Form
    {
        public SlaveForm()
        {
            InitializeComponent();
        }
 
        private void SendB_Click(object sender, EventArgs e)
        {
            //По клику на кнопке пишем данные из текстбокса в свойство статического класса
            StaticData.DataBuffer = OutboxTB.Text;
        }
    }

Если открывать дочернюю форму как диалог, данные в основной форме обновятся после закрытия дочерней. В противном случае данные обновятся сразу же. Подобный подход удобен, когда нужно организовать одновременный обмен данными между двумя формами. Причем, в отличие от большинства других вариантов, такой способ обмена доступен и для равнозначных форм (запущенных от одного, не участвующего в обмене родителя — например, MDI-окна). Достаточно просто заставить каждую форму слушать определенное событие статического класса-буфера.

На данный момент вроде как все. Скорее всего что-то забыл, поэтому к критике в комментариях буду прислушиваться особенно внимательно.
Best Regards, Aexx

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



5



RRS feed

  • Remove From My Forums

 none

Какие способы передачи переменных между формами?

RRS feed

  • Общие обсуждения

  • Какие способы передачи переменных между формами в приложениях Windows Form на языке Visual C#?

    • Изменен тип
      I.Vorontsov
      22 марта 2010 г. 11:23
    • Перемещено
      Tagore Bandlamudi
      2 октября 2010 г. 21:58
      MSDN Forums consolidation (От:Разработка Windows-приложений)

Все ответы

  • Я обычно делаю свойство или публичный член класса формы. Но тогда надо передавать сам объект формы. Можно сделать сторонний Static Class для обмена данными.

    Это корректно или обычно делают как-то иначе?

  • Один из способов передачи параметров между формами:

    — в первой форме (Form1) объявить public переменную с модификатором static, например:

    static public int i;

    — задать значение ей, например при загрузке формы:

    i = 5;

    — во второй форме можно обратиться к переменной, например вывести значение переменной в заголовок формы:

    this.Text = Form1.i.ToString();

  • На мой взгляд использовать сторонний Static Class целесообразно для «долгого» хранения переменных…

    Если необходимо единовременно передать данные между формами, то делаю следующее:

    1.В форму куда необходимо передать данные (ФормаКуда) в коде пишем:

    public partial class ФормаКуда: Form
        {
            ФормаОтКуда mainForm = null;
            public Otsrochka(ФормаОтКуда main)

                   {
              InitializeComponent();
              mainForm = main;
            }

    2. Вызываем ФормаКуда из  ФормаОтКуда:

     ФормаКуда FormNew = new ФормаКуда (this);
     FormNew .ShowDialog();
    3.  Манипулируем данными в ФормаКуда через mainForm. При этом необходимо чтобы переменные в ФормаОтКуда были Public

In the comments to the accepted answer, Neeraj Gulia writes:

This leads to tight coupling of the forms Form1 and Form2, I guess instead one should use custom events for such kind of scenarios.

The comment is exactly right. The accepted answer is not bad; for simple programs, and especially for people just learning programming and trying to get basic scenarios to work, it’s a very useful example of how a pair of forms can interact.

However, it’s true that the coupling that example causes can and should be avoided, and that in the particular example, an event would accomplish the same thing in a general-purpose, decoupled way.

Here’s an example, using the accepted answer’s code as the baseline:

Form1.cs:

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

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 frm = new Form2();

        frm.Button1Click += (s1, e1) => Lbl.Text = ((Form2)s1).Message;

        frm.Show();
    }
}

The above code creates a new instance of Form2, and then before showing it, adds an event handler to that form’s Button1Click event.

Note that the expression (s1, e1) => Lbl.Text = ((Form2)s1).Message is converted automatically by the compiler to a method that looks something similar to (but definitely not exactly like) this:

private void frm_Message(object s1, EventArgs e1)
{
    Lbl.Text = ((Form2)s1).Message;
}

There are actually lots of ways/syntaxes to implement and subscribe the event handler. For example, using an anonymous method as the above, you don’t really need to cast the sender parameter; instead you can just use the frm local variable directly: (s1, e1) => Lbl.Text = frm.Message.

Going the other way, you don’t need to use an anonymous method. You could in fact just declare a regular method just like the compiler-generated one I show above, and then subscribe that method to the event: frm.Button1Click += frm_Message; (where you have of course used the name frm_Message for the method, just as in my example above).

Regardless of how you do it, of course you will need for Form2 to actually implement that Button1Click event. That’s very simple…

Form2.cs:

public partial class Form2 : Form
{
    public event EventHandler Button1Click;

    public string Message { get { return txtMessage.Text; } }

    public Form2()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        EventHandler handler = Button1Click;

        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }
}

In addition to the event, I’ve also declared a property Message that exposes the Text property (and only the Text property, and only as read-only in fact) of the txtMessage control. This allows the subscriber to the event to get the value and do whatever it needs to with it.

Note that all that the event does is to alert the subscriber that the button has in fact been clicked. It’s up to the subscriber to decide how to interpret or react to that event (e.g. by retrieving the value of the Message property and assigning it to something).

Alternatively, you could in fact deliver the text along with the event itself, by declaring a new EventArgs sub-class and using that for the event instead:

public class MessageEventArgs : EventArgs
{
    public string Message { get; private set; }

    public MessageEventArgs(string message)
    {
        Message = message;
    }
}

public partial class Form2 : Form
{
    public event EventHandler<MessageEventArgs> Button1Click;

    public Form2()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        EventHandler handler = Button1Click;

        if (handler != null)
        {
            handler(this, new MessageEventArgs(txtMessage.Text));
        }
    }
}

Then the subscriber can just retrieve the message value directly from the event object:

frm.Button1Click += (sender, e) => Lbl.Text = e.Message;

The important thing note in all of the above variations is that at no point does the class Form2 need to know anything about Form1. Having Form1 know about Form2 is unavoidable; after all, that’s the object that will create a new Form2 instance and use it. But the relationship can be asymmetrical, with Form2 being usable by any object that needs the features it offers. By exposing the functionality as an event (and optionally with a property), it makes itself useful without limiting its usefulness to only the Form1 class.

Многие, кто начинал изучение WinForm приложений, сталкивались с проблемой обмена данными между окнами программы. Обмен данными между формами сводится к трем основным принципам: передача параметров в форму, получение данных из формы, изменение значений другой формы. Начнем по порядку.

1) Передача параметров в форму. Любой класс, должен иметь конструктор, и WinForm в этом случае не исключение. А следовательно очевидным является тот факт, что передача данных необходимых для инициализации формы необходимо проводить именно через конструктор формы. Приведем пример.

Создадим WinForm и перейдем к коду. Наблюдаем следующую картину:

public partial class Form1 : Form
    {
        public Form1() // <-- Конструктор формы по умолчанию
        {
            InitializeComponent();
        } }

Допустим на данной форме размещен элемент textBox в который мы хотим установить значение, при открытии нашей формы. Тогда модифицируем наш код следующим образом:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        } 
        public Form1(string text) // <-- Новый конструктор формы
        {
            InitializeComponent();
            textBox.Text = text;
        }
    }

Важно: Все действия, выполняемые с объектами формы должны быть произведены после функции InitializeComponent()!

2-3) По сути задача получения данных из формы и изменение данных в форме сводистя к одной задаче. Пусть у нас есть две формы Form1 и Form2. В первой форме у нас есть три кнопки: open, read, write . Первая откроет вторую форму, в которой есть элемент textBox, Вторая покажет сообщение с текстом, введенным в textBox формы номер два, третья очистит textBox из Form2. Имеем:

public partial class Form1 : Form
    {
        private Form2 F2 = new Form2();
 //<--Объявляем форму два как элемент класса формы один

        public Form1()
        {
            InitializeComponent();
        }
        private void open_Click(object sender, EventArgs e)
        {
            F2.ShowDialog();
        }
        private void read_Click(object sender, EventArgs e)
        {
            MessageBox.Show(F2.textBoxValue);
        }
        private void write_Click(object sender, EventArgs e)
        {
            F2.textBoxValue = String.Empty;
        }
    }

    public partial class Form2 : Form
    {
        public string textBoxValue
//<--Данная конструкция позволяет получить доступ
//к private элементам формы
        {
            get { return textBox.Text; }
            set { textBox.Text = value; }
        }
        public Form2()
        {
            InitializeComponent();
        }
    }

Вот и все. Оказалось не все так сложно 😉

  • Download demo project — 51.01 KB

Sample Image - PassData.jpg

Passing Data Between Forms

Introduction

Some of you would have faced a scenario where you wanted to pass data from one form to another in WinForms. Honestly, I too had a similar problem (that’s why I am writing this article!).

There are so many methods (How many? I don’t know) to pass data between forms in Windows application. In this article, let me take four important (easiest) ways of accomplishing this:

  1. Using constructor
  2. Using objects
  3. Using properties
  4. Using delegates

Let us see all the above methods in detail in the following sections.

For data to be passed between forms using any of the above methods, we need two forms and some controls. Let us start by following the steps given below.

Step 1

Create a new project and select Windows application. This will create a default form as “Form1”. We can use this form for sending data.

Step 2

Add a textbox and a button to the form.

Step 3

Add another Windows Form for receiving the data and to display it. Right click the project and select Add->Add Windows Form. Enter a name or use the default name “Form2.cs” and click ok button.

Step 4

Add a label to the second form to display the text from form1.

The Constructor Approach

This could be the easiest method of all. A method is invoked whenever you instantiate an object. This method is called a constructor. Code a constructor for form2 class with one string parameter. In the constructor, assign the text to the label’s text property. Instantiate form2 class in form1’s button click event handler using the constructor with one string parameter and pass the textbox’s text to the constructor.

Follow the steps given below:

Step 1

Code a constructor for form2 class as below:

public Form2(string strTextBox)
{
  InitializeComponent(); 
  label1.Text=strTextBox;
}

Step 2

Instantiate form2 class in form1’s button click event handler as below:

private void button1_Click(object sender, System.EventArgs e)
{
    Form2 frm=new Form2(textBox1.Text);
    frm.Show();
}

The Object Approach

Objects are reference types, and are created on the heap, using the keyword new. Here we are going to pass data using objects. The approach is simple; in form2 we are going to instantiate form1 class.

Then instantiate form2 in the button click event handler of form1. After this we are going to pass form1 object to the form2 using form2’s form1 object. The last step is to invoke the form2 window by calling the form2’s show method.

Follow the below steps:

Step 1

Change the access modifier for textbox in form1 to public:

public class Form1 : System.Windows.Forms.Form
{  
 public System.Windows.Forms.TextBox textBox1;

Step 2

In the button click event-handler, add the following code:

private void btnSend_Click(object sender, System.EventArgs e)
{
    Form2 frm= new Form2();
    frm.frm1=this;
    frm.Show();
}

Step 3

In form2.cs, instantiate form1 class:

public class Form2 : System.Windows.Forms.Form
{
     private System.Windows.Forms.Label label1;
     public Form1 frm1;

Step 4

In Form2’s Load method, type cast the object (frm1) of form1 to Form1 and access form1’s textbox and assign its text to label’s text.

private void Form2_Load(object sender, System.EventArgs e)
{
    label1.Text=((Form1)frm1).textBox1.Text;
}

The Properties Approach

Properties allow clients to access class state as if they were accessing member fields directly, while actually implementing that access through a class method. In this method, we are going to add one property to each form. In form1 we are going to use one property for retrieving value from the textbox and in form2, one property to set the label’s text property. Then, in form1’s button click event handler, we are going to instantiate form2 and use the form2’s property to set the label’s text.

Follow the below steps:

Step 1

Add a property in form1 to retrieve value from textbox:

public string _textBox1
{
    get{return textBox1.Text;}
}

Step 2

Add a property in form2 to set the labels’ text:

public string _textBox
{
   set{label1.Text=value;}
}

Step 3

In form1’s button click event handler, add the following code:

private void button1_Click(object sender, System.EventArgs e)
{
     Form2 frm=new Form2();
     frm._textBox=_textBox1;
     frm.Show();
}

The Delegates Approach

Technically, a delegate is a reference type used to encapsulate a method with a specific signature and return type. You can encapsulate any matching method in that delegate. Here we are going to create a delegate with some signature and assign a function to the delegate to assign the text from textbox to label.

Follow the below steps:

Step 1

Add a delegate signature to form1 as below:

public delegate void delPassData(TextBox text);

Step 2

In form1’s button click event handler, instantiate form2 class and delegate. Assign a function in form2 to the delegate and call the delegate as below:

private void btnSend_Click(object sender, System.EventArgs e)
{
    Form2 frm= new Form2();
    delPassData del=new delPassData(frm.funData);
    del(this.textBox1);
    frm.Show();
}

Step 3

In form2, add a function to which the delegate should point to. This function will assign textbox’s text to the label:

public void funData(TextBox txtForm1)
{
    label1.Text = txtForm1.Text;
}

Conclusion

These four approaches are very simple in implementing data passing between forms. There are also other methods available in accomplishing the same. Source code for the methods I stated above is given at the top for download. It is time for you to put on your thinking cap and find other ways of doing this. Happy coding!!!

History

  • 16th May, 2006: Initial post

Thiagu is living in Bangalore, India. He has started coding when he was 12 years old. His native is Madurai, a historic city in south India. He loves to code in C#. He frequents code project when he is not coding. Thiagu loves reading Dan Brown and Michael Crichton novels. He is very much interested in Artificial Intelligence (AI). To view his blog — http://csharpnet.blogspot.com

  • Download demo project — 51.01 KB

Sample Image - PassData.jpg

Passing Data Between Forms

Introduction

Some of you would have faced a scenario where you wanted to pass data from one form to another in WinForms. Honestly, I too had a similar problem (that’s why I am writing this article!).

There are so many methods (How many? I don’t know) to pass data between forms in Windows application. In this article, let me take four important (easiest) ways of accomplishing this:

  1. Using constructor
  2. Using objects
  3. Using properties
  4. Using delegates

Let us see all the above methods in detail in the following sections.

For data to be passed between forms using any of the above methods, we need two forms and some controls. Let us start by following the steps given below.

Step 1

Create a new project and select Windows application. This will create a default form as “Form1”. We can use this form for sending data.

Step 2

Add a textbox and a button to the form.

Step 3

Add another Windows Form for receiving the data and to display it. Right click the project and select Add->Add Windows Form. Enter a name or use the default name “Form2.cs” and click ok button.

Step 4

Add a label to the second form to display the text from form1.

The Constructor Approach

This could be the easiest method of all. A method is invoked whenever you instantiate an object. This method is called a constructor. Code a constructor for form2 class with one string parameter. In the constructor, assign the text to the label’s text property. Instantiate form2 class in form1’s button click event handler using the constructor with one string parameter and pass the textbox’s text to the constructor.

Follow the steps given below:

Step 1

Code a constructor for form2 class as below:

public Form2(string strTextBox)
{
  InitializeComponent(); 
  label1.Text=strTextBox;
}

Step 2

Instantiate form2 class in form1’s button click event handler as below:

private void button1_Click(object sender, System.EventArgs e)
{
    Form2 frm=new Form2(textBox1.Text);
    frm.Show();
}

The Object Approach

Objects are reference types, and are created on the heap, using the keyword new. Here we are going to pass data using objects. The approach is simple; in form2 we are going to instantiate form1 class.

Then instantiate form2 in the button click event handler of form1. After this we are going to pass form1 object to the form2 using form2’s form1 object. The last step is to invoke the form2 window by calling the form2’s show method.

Follow the below steps:

Step 1

Change the access modifier for textbox in form1 to public:

public class Form1 : System.Windows.Forms.Form
{  
 public System.Windows.Forms.TextBox textBox1;

Step 2

In the button click event-handler, add the following code:

private void btnSend_Click(object sender, System.EventArgs e)
{
    Form2 frm= new Form2();
    frm.frm1=this;
    frm.Show();
}

Step 3

In form2.cs, instantiate form1 class:

public class Form2 : System.Windows.Forms.Form
{
     private System.Windows.Forms.Label label1;
     public Form1 frm1;

Step 4

In Form2’s Load method, type cast the object (frm1) of form1 to Form1 and access form1’s textbox and assign its text to label’s text.

private void Form2_Load(object sender, System.EventArgs e)
{
    label1.Text=((Form1)frm1).textBox1.Text;
}

The Properties Approach

Properties allow clients to access class state as if they were accessing member fields directly, while actually implementing that access through a class method. In this method, we are going to add one property to each form. In form1 we are going to use one property for retrieving value from the textbox and in form2, one property to set the label’s text property. Then, in form1’s button click event handler, we are going to instantiate form2 and use the form2’s property to set the label’s text.

Follow the below steps:

Step 1

Add a property in form1 to retrieve value from textbox:

public string _textBox1
{
    get{return textBox1.Text;}
}

Step 2

Add a property in form2 to set the labels’ text:

public string _textBox
{
   set{label1.Text=value;}
}

Step 3

In form1’s button click event handler, add the following code:

private void button1_Click(object sender, System.EventArgs e)
{
     Form2 frm=new Form2();
     frm._textBox=_textBox1;
     frm.Show();
}

The Delegates Approach

Technically, a delegate is a reference type used to encapsulate a method with a specific signature and return type. You can encapsulate any matching method in that delegate. Here we are going to create a delegate with some signature and assign a function to the delegate to assign the text from textbox to label.

Follow the below steps:

Step 1

Add a delegate signature to form1 as below:

public delegate void delPassData(TextBox text);

Step 2

In form1’s button click event handler, instantiate form2 class and delegate. Assign a function in form2 to the delegate and call the delegate as below:

private void btnSend_Click(object sender, System.EventArgs e)
{
    Form2 frm= new Form2();
    delPassData del=new delPassData(frm.funData);
    del(this.textBox1);
    frm.Show();
}

Step 3

In form2, add a function to which the delegate should point to. This function will assign textbox’s text to the label:

public void funData(TextBox txtForm1)
{
    label1.Text = txtForm1.Text;
}

Conclusion

These four approaches are very simple in implementing data passing between forms. There are also other methods available in accomplishing the same. Source code for the methods I stated above is given at the top for download. It is time for you to put on your thinking cap and find other ways of doing this. Happy coding!!!

History

  • 16th May, 2006: Initial post

Thiagu is living in Bangalore, India. He has started coding when he was 12 years old. His native is Madurai, a historic city in south India. He loves to code in C#. He frequents code project when he is not coding. Thiagu loves reading Dan Brown and Michael Crichton novels. He is very much interested in Artificial Intelligence (AI). To view his blog — http://csharpnet.blogspot.com

Like this post? Please share to your friends:
  • Windows forms как открыть другую форму
  • Windows forms как запретить изменять размер окна
  • Windows forms запретить изменение размера формы
  • Windows forms доступ к элементам другой формы
  • Windows forms для visual studio 2019 скачать