Общаться между двумя окнами в C #

У меня две формы: одна - основная форма, а другая - форма вариантов. Например, скажем, что пользователь нажимает на мое меню в основной форме: Tools -> Optionsэто приведет к отображению формы параметров.

Мой вопрос в том, как я могу отправить данные из моей формы в мою основную форму? Я знаю, что могу использовать свойства, но у меня много вариантов, и это похоже на утомительную вещь.

Итак, каков наилучший способ?

c#,winforms,properties,

34

Ответов: 11


54 принят

public partial class Form1: Form {public Form1 () {InitializeComponent (); } private void button1_Click (отправитель объекта, EventArgs e) {Form2 frm = new Form2 (); frm.Button1Click + = (отправитель, e) => Lbl.Text = ((Form2) отправитель) .Message; frm.Show (); }} запускаются формы Form2. Button1Click имеет перегруженный конструктор, который принимает форму вызова в качестве аргумента и предоставляет ссылку (отправитель, e) => Lbl.Text = ((Form2) отправитель). Члены сообщения. Это решает проблему связи. Например, я обнаружил свойство Label как public в private void frm_Message (отправитель объекта, EventArgs e) {Lbl.Text = ((Form2) отправитель) .Message; }, который изменяется в отправителе.

При таком подходе вы можете общаться по-разному.

Загрузить ссылку для примера проекта

// Ваш frm

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

// Ваш frm.Button1Click + = frm_Message;

frm_Message

старый текст http://demo.ruchitsurati.net/files/frm1.png

старый текст http://demo.ruchitsurati.net/files/frm2.png


11 ов

В комментариях к принятому ответу, Нерайдж Гулия пишет:

Это приводит к плотной связи форм Form1 и Button1Click, я думаю, вместо этого следует использовать пользовательские события для таких сценариев.

Комментарий в точности прав. Принятый ответ неплох; для простых программ, и особенно для людей, которые просто изучают программирование и пытаются использовать базовые сценарии для работы, это очень полезный пример того, как может взаимодействовать пара форм.

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

Вот пример, используя код принятого ответа в качестве базовой линии:

Form1.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);
        }
    }
}

Вышеприведенный код создает новый экземпляр Form2, а затем перед его отображением добавляет обработчик события к событию этой формы Message.

Обратите внимание, что выражение Textавтоматически преобразуется компилятором в метод, который выглядит примерно так (но определенно не совсем так):

Text

На самом деле существует множество способов / синтаксисов для реализации и подписки на обработчик событий. Например, используя анонимный метод, как указано выше, вам действительно не нужно указывать txtMessageпараметр; вместо этого вы можете просто использовать frmлокальную переменную непосредственно: Message.

Идя в другую сторону, вам не нужно использовать анонимный метод. Фактически вы можете просто объявить обычный метод, как и созданный компилятором, который я покажу выше, а затем подпишу этот метод для события: EventArgs(где вы, конечно, использовали имя 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)); } } } для метода, как и в моем примере выше).

Независимо от того, как вы это делаете, вам, конечно же, понадобится Form2реализовать это frm.Button1Click += (sender, e) => e.Message; событие. Это очень просто!

Form2.cs:

Form2

В дополнение к случаю, я также объявил свойство , Form1что выставляет Textимущество (и только в Textсобственность, а только для чтения только на самом деле) от Form1контроля. Это позволяет подписчику на событие получить значение и делать с ним все, что ему нужно.

Обратите внимание, что все, что делает это событие, - это предупредить абонента о том, что кнопка нажата. Абонент должен решить, как интерпретировать или реагировать на это событие (например, путем получения значения Form2свойства и назначения его чему-то).

Кроме того, вы могли бы фактически доставить текст вместе с самим событием, объявив новый Form2подкласс и используя его для этого события:

Form2

Затем абонент может просто получить значение сообщения непосредственно из объекта события:

Form1


Важная вещь во всех вышеперечисленных вариантах заключается в том, что ни в коем случае класс не Form2должен ничего знать Form1. Знание Form1об Form2этом неизбежно; в конце концов, это объект, который будет создавать новый Form2экземпляр и использовать его. Но отношения могут быть асимметричными, и Form2они могут использоваться любым объектом, которому нужны функции, которые он предлагает. Предоставляя функциональность как событие (и необязательно со свойством), оно становится полезным, не ограничивая его полезность только Form1классом.


6

Лучшим в этом случае будет OptionsServiceдоступ к некоторому классу / интерфейсу IServiceProvider.

Просто добавьте событие, когда что-то изменится, и остальная часть приложения сможет ответить на него.


1

Свойства - это один вариант, общий статический класс - еще один вариант, события - еще один вариант ...


1

Вы можете попробовать AutoMapper . Сохраняйте свои параметры в отдельном классе, а затем используйте AutoMapper для передачи данных между классом и формой.

C #, WinForms, свойства,