Передача данных обратно в первую форму из второй формы в C#

У меня две формы. Скажи форма, FormB.

из FormA я назвал FormB, используя frmB.Show();

в FormB у меня есть два текстовых поля и элементы управления combobox. Предположим, пользователь вводит некоторые данные в эти два текстовых поля и выбрал элемент из combobox в Form2 и нажал OK.

после щелчка я хочу, чтобы эти текстовые поля пользователь ввел значения, combobox выбранное значение элемента обратно в форма.

Как я могу достичь этого с помощью C#.

9 ответов


или вы можете передать объект из FormA в FormB и привязать его свойства к элементам управления в FormB. Если вы хотите, чтобы форма была уведомлена при нажатии кнопки OK, вы можете объявить событие в своем классе контейнера данных, подписаться на него в форме и запустить его из FormB.

Be DataContainer некоторый класс, который вы определяете

public class DataContainer
{
    public event EventHandler AcceptedChanges;
    protected virtual void OnAcceptedChanges()
    {
        if ((this.AcceptedChanges != null))
        {
            this.AcceptedChanges(this, EventArgs.Empty);
        }
    }

    public void AcceptChanges()
    {
        this.OnAcceptedChanges();
    }

    public string Text1 { get; set; }
    public string Text2 { get; set; }
}

in FormA:

    private void button4_Click(object sender, EventArgs e)
{
    DataContainer data = new DataContainer();
    data.Text1 = "text1";
    data.Text1 = "text2";

    Form2 frm = new Form2();
    frm.Data = new DataContainer();
    data.AcceptedChanges += new EventHandler(data_AcceptedChanges);
    frm.Show();
}

void data_AcceptedChanges(object sender, EventArgs e)
{
    // your code here
}

и в FormB:

public DataContainer Data { get; set; }

private void Form2_Load(object sender, EventArgs e)
{
    textBox1.DataBindings.Add(new Binding("Text", Data, "Text1"));
    textBox2.DataBindings.Add(new Binding("Text", Data, "Text2"));
}

private void button1_Click(object sender, EventArgs e)
{
    Data.AcceptChanges();
}

вы также должны реализовать INotifyPropertyChanging и INotifyPropertyChanged в классе DataContainer, чтобы играть хорошо с привязками.


Я подошел к простому .. маленькие украшения..

  1. создайте открытые переменные в своем классе формы, т. е.

    публичная строка passVariable1 ="";

  2. если у вас есть текстовые поля, перейдите к свойствам, затем нажмите на молнию и дважды щелкните пустой TextChanged eventhandler. Это создаст фрагмент кода в начале кода, который будет выполнен при изменении содержимого текстового поля .. в этом блоке кода назначьте содержимое текстового поля соответствующей открытой переменной.

  3. т. е. моя общая переменная

    public string issue ="";

    private void txtIssue_TextChanged(отправитель объекта, EventArgs e) { issue = txtIssue.Текст; }

  4. добавьте кнопку и создайте событие click для этой кнопки (просто дважды щелкните кнопку на панели "дизайн"). В нажмите блок кода события установите результат dilog в ok и скройте

    этого.DialogResult = DialogResult.OK;

    этого.Hide();

  5. в коде родительского окна проверьте результат диалога и возьмите данные формы из открытых переменных дочерней формы

if (f.ShowDialog() == DialogResult.OK)
  {
      string b  = f.issue;             
      string e = f.year;
      string f = f.month;
  };

в сценарии, который вы описываете, я бы, вероятно, назвал frmB.ShowDialog(), а не frmB.Show().

// Inside FormA open frmB as a modal dialog waiting for 
// OK or Cancel result using the following  statement

if (frmB.ShowDialog() == DialogResult.OK)
{
   // Retrieve selected values from frmB here (while frmB is still not disposed)
}

преимущества ShowDialog() вы:

  1. получить возвращаемое значение из формы легко позволяет определить, что OK (а не отмена) был нажат, чтобы закрыть его.
  2. форма не сразу удаляется при закрытии, что позволяет получить значения, которые вы хотите.
  3. открыв frmB как модальный диалог, вы избегайте необходимости проверять сложности, которые могут возникнуть, если пользователь начинает взаимодействовать с formA во время открытия frmB.

Примечание: при проектировании frmB вы должны установить DialogResult свойство кнопки OK-control to DialogResult.OK для того, чтобы форма возвращала правильный DialogResult при нажатии этой кнопки (Альтернативно можно также установить this.DialogResult в обработчике событий щелчка кнопки OK)


Вы можете создать EventHandler на FormB, на который FormA подпишется. Кроме того, добавьте в FormB несколько общедоступных свойств, представляющих данные, которые должна использовать FormA. Затем, когда FormB запускает событие, форма будет знать, чтобы обновить свои данные.

Примечание: ключевым принципом в этом примере является реализация EventHandler (вы можете создать свой собственный тип обработчика событий), который уведомляет FormA, когда данные готовы к обновлению/просмотру/и т. д. Надеюсь, этот пример позволит вам увидеть, как можно реализовать обработчик событий для вашей конкретной ситуации.

пример:

форма -

public partial class FormA : Form
{
    //FormA has a private instance of FormB
    private FormB formB = null;
    public FormA()
    {
        InitializeComponent();
    }

    void formB_OnDataAvailable(object sender, EventArgs e)
    {
        //Event handler for when FormB fires off the event
        this.label1.Text = string.Format("Text1: {0}\r\nText2: {1}", 
            formB.Text1, formB.Text2);
    }

    private void InitializeFormB()
    {
        this.formB = new FormB();

        //FormA subscribes to FormB's event
        formB.OnDataAvailable += new EventHandler(formB_OnDataAvailable);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.InitializeFormB();
        formB.Show();
    }
}

FormB -

public partial class FormB : Form
{
    //Event that fires when data is available
    public event EventHandler OnDataAvailable;

    //Properties that expose FormB's data
    public string Text1 { get; private set; }
    public string Text2 { get; private set; }

    public FormB()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        //Set the exposed properties, then fire off the event.
        this.Text1 = this.textBox1.Text;
        this.Text2 = this.textBox2.Text;

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

Как насчет использования событий и делегатов? Смотрите это http://colinmackay.шотландец/2005/04/22/прохождение-значения-между-формы-в-сеть/


грязное, но и самое быстрое решение-сделать эти элементы управления публичных. Это можно сделать, добавив слово public в Form2.Decisgner.cs файл. Если FormA имеет переменную-член или локальную переменную FormB, вы можете получить доступ к элементу управления (скажем TextBox1) с помощью:

frmB.TextBox1.Text

который теперь доступен и за пределами FormB.


у меня была такая же проблема, и я придумал идею, которая немного отличается. В моем сценарии я делаю программу флэш-карты для моих младших двух детей, и я хотел бы иметь возможность вернуть ответ, предоставленный родительской форме (новая дочерняя форма для каждого нового вопроса флэш-карты, чтобы родительская форма могла обновить, сколько осталось, сколько правильно, сколько неправильно и т. д.) без необходимости добавлять значения в базу данных. Кажется перебор за то, что должно быть простым. Что я сделал, чтобы создать класс с 3 каждого типа переменной. Я решил, что для большинства работ достаточно трех типов.

Это пример моего нового класса:

namespace ClassNamespace
{
  public class ValueHolder
  {
    public int intValue1 { get; set; }
    public int intValue2 { get; set; }
    public int intValue3 { get; set; }
    public long longValue1 { get; set; }
    .
    .
    .
  }
}

Я создаю новый ValueHolder (ValueHolder vh;) из родительской формы и передаю его дочерней форме. В дочерней форме я создаю новый ValueHolder, а затем устанавливаю его равным объекту ValueHolder, отправленному в конструкторе класса дочерней формы. Теперь, когда клавиша enter нажата (ответ дан), я могу установить vh.intValue1 равно этому.answerBox.текст.;.. ну, я должен использовать int.tryparse (); но вы получаете идею. Тогда мне нужно только ссылаться на ВХ.intValue1 из родительской формы, чтобы получить введенное значение.

родительской форме:

for (int i = 0; i < limit; i++)
{
  ValueHolder vh = new ValueHolder();

  ChildClass cc = new ChildClass(vh);
  MessageBox.Show(vh.intValue1.ToString()); //to test that it works
}

и ребенка форме:

ValueHolder vh;

public ChildClass (ValueHolder vhIncoming)
{
  vh = vhIncoming;
}

private void answerBox_KeyDown(object sender, KeyEventArgs e)
{
  if (e.KeyCode == Keys.Enter)
  {
    vh.intValue1 = 1234;
  }
}

Это, видимо, самое простое решение для моего сценария. Я знаю, что этот вопрос старый, но хотел добавить этот вариант для любого, кто находится в подобной позиции. Просто добавьте класс в свой проект, добавьте больше типа или больше типов к классу по мере необходимости, повторите полоскание для будущих проектов.


Если его на той же странице вы должны иметь возможность читать его непосредственно из ваших элементов управления как Textbox1.Текст И Textbox2.Текст, Combobox.SelectedValue (я думаю) Но если его на разных страницах используют переменные сеанса, такие как: Сессия["дата1"] = текстовое поле textbox1.Текст; Сеанс ["date2"] = TextBox2.Текст; Сеанс ["comboValue"] = Combobox.SelectedValue; и использовать их для заполнения формы


Это будет зависеть от того, как вы обычно дизайн приложения.

  • вы можете работать с помощью события управляемая система, где вы создадите события и делегаты. Упоминается @Dave81
  • или вы можете создать свойства, которые возвращает заданные / выбранные значения так что родитель может получить их из объекта (хотел сказать диалог но не уверен, что вы используете).
  • или вы можете следовать @zmilojko и просто установите их public, который в основном по свойствам, но больше к темной стороне кодирования практика :Д

все это будет работать, но все зависит от того, как вы хотите, чтобы ваши приложения были структурированы.