Лучший способ общения между формами? - PullRequest
3 голосов
/ 14 декабря 2010

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

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

Возможно, я могу:

  • Создать статический класс (или Properties.Settings) для глобальных настроек.Минусы: каждое изменение данных необходимо скопировать в класс, я ищу что-то более удобное и элегантное.
  • Используйте некрасивый способ доступа к элементам управления из приложения.OpenForms - исправляет проблему передачи главной формы в качестве параметра.Минусы: не очень стабильный.
  • Сделай что-нибудь еще, о чем я не думал.Предложения?Минусы: пока не знаю что это такое.

Ответы [ 4 ]

1 голос
/ 14 декабря 2010

Хороший способ - объявить делегатов в форме, которые хотят начать общение.Вам нужен делегат и функция обратного вызова:

public delegate void SetValueDelegate(string value);
public SetValueDelegate SetValueCallback;

Затем к этому делегату можно прикрепить другую форму.В этот момент обе формы должны знать друг друга, но не после этого момента:

firstForm.SetValueCallback += new SetValueDelegate(secondForm.SetValueFunction);

Вторая форма должна объявить функцию, которая соответствует определению делегата:

public void SetValueFunction(string value)
{
    // do something
}

Теперьпервая форма может использовать делегат для использования функции второй формы (и все другие формы или классы, которые были присоединены к делегату:

SetValueCallback(txtParam.Text);

Edit: сделал полный пример

using System;

namespace DelegateTest
{
    public delegate void SetValueDelegate(string value);

    public class Class1
    {
        public SetValueDelegate SetValueCallBack;

        public void Test()
        {
            if(SetValueCallBack != null)
            {
                SetValueCallBack("Hello World!");
            }
        }
    }

    public class Class2
    {
        public void SetValueFunction(string value)
        {
            Console.WriteLine(value);
        }
    }

    public class Launcher
    {
        public static void Main(string[] args)
        {
            Class1 c1 = new Class1();
            Class2 c2 = new Class2();
            c1.SetValueCallBack += new SetValueDelegate(c2.SetValueFunction);
            c1.Test();
        }
    }
}
1 голос
/ 14 декабря 2010

Ваша идея конструктора, вероятно, является наиболее надежным способом связи с основной формой.Ваша подформа будет делать что-то вроде следующего:

public class SubForm : Form
{
    public SubForm(MainForm parentForm)
    {
        _parentForm = parentForm;
    }

    private MainForm _parentForm;

    private void btn_UpdateClientName_Click(object sender, EventArgs e)
    {
        _parentForm.UpdateClientName(txt_ClientName.Text);
    }
}

И затем вы будете открывать открытые методы для вашего MainForm:

public class MainForm : Form
{
    public void UpdateClientName(string clientName)
    {
        txt_MainClientName.Text = clientName;
    }
}

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

public class MainForm : Form
{
    private SubForm1 _subForm1;
    private SubForm2 _subForm2;

    public MainForm()
    {
        _subForm1 = new SubForm1();
        _subForm2 = new SubForm2();

        _subForm1.ClientUpdated += new EventHandler(_subForm1_ClientUpdated);
        _subForm2.ClientUpdated += new EventHandler(_subForm2_ProductUpdated);
    }

    private void _subForm1_ClientUpdated(object sender, EventArgs e)  
    {
        txt_ClientName.Text = _subForm1.ClientName; // Expose a public property
    }

    private void _subForm2_ProductUpdated(object sender, EventArgs e)  
    {
        txt_ProductName.Text = _subForm2.ProductName; // Expose a public property
    }
}
0 голосов
/ 14 декабря 2010

Самый гибкий, масштабируемый (и ИМХО самый профессиональный) способ сделать это - использовать CAB (Composite Application Block) .Проще говоря, CAB - это набор из 2-3 сборок, в которых реализовано большое количество сантехники, необходимой для правильной реализации сложных приложений пользовательского интерфейса , и он предоставляет эту библиотеку пользователю библиотеки.Среди прочего у него есть очень хорошая система событий и команд (как в шаблоне команд).

Недостаток: требуется некоторое время для изучения и не очень тривиально для понимания.

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

0 голосов
/ 14 декабря 2010

Вы можете использовать встроенное свойство Tag формы, которая является классом "object".

публичная форма1 () { (ComplicatedDataStructure) Tag = new ComplicatedDataStracture (); } , , form1 = новая Form1 (); , , form2 = новая Form2 (); , , form2.Tag = form1.Tag;

так что form2.Tag равен объекту "ComplicatedDataStracture";

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...