Отправка данных из дочерней формы в родительскую форму TextBox - PullRequest
3 голосов
/ 01 апреля 2009

У меня есть родительская форма, которая содержит «HUD» с именем, фамилией и т. Д. Одной из дочерних форм является форма поиска. Когда пользователь выбирает члена из результатов, отображаемых в DataGrid, я хочу, чтобы соответствующая информация заполняла HUD. Я создал класс HUD с переменными для каждого значения и метод с именем UpdateHUD (). Я не уверен, как заставить это работать. У меня есть ссылка на форму поиска родительской формы, содержащей HUD, например:

public frmWWCModuleHost _frmWWCModuleHost;

Это код, который я использую для встраивания форм. Я не использую MDI.

 public static void ShowFormInContainerControl(Control ctl, Form frm)
    {
        frm.TopLevel = false;
        frm.FormBorderStyle = FormBorderStyle.None;
        frm.Dock = DockStyle.Fill;
        frm.Visible = true;
        ctl.Controls.Add(frm);
    }

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

private void dgvSearchResults_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        _frmWWCModuleHost = new frmWWCModuleHost();
        _frmWWCModuleHost.tbxHUD_LastName.Text = dgvSearchResults.CurrentRow.Cells[1].FormattedValue.ToString();
        _frmWWCModuleHost.tbxHUD_LastName.Invalidate();
        _frmWWCModuleHost.FormPaint();
    }

Заранее спасибо!

~ Патрик


EDIT


dgvSearchResults_CellContentClick теперь актуально. Когда я перехожу этот код, он получает правильное значение здесь, но он никогда не обновляет фактический HUD.


РЕДАКТИРОВАТЬ 2


Моя проблема в том, что я объявляю NEW frmWWCModuleHost вместо передачи ссылки на существующую? Я все еще довольно слаб в моем понимании этого.


РЕДАКТИРОВАТЬ 3


Я «решил» это, выполнив следующее: В родительской форме, где я объявляю дочернюю форму, я передаю this в качестве параметра. Затем в конструктор дочерней формы я добавил _frmWWCModuleHost = m_parent; У меня есть метод UpdateHUD () в родительской форме, и я вызываю его из события _CellClick для дочернего элемента.

Теперь перефразирую мой вопрос; Что-то явно не так с этим?

Ответы [ 3 ]

5 голосов
/ 01 апреля 2009

Когда поиск дочерней формы завершится, вызовите событие «SearchCompleted». Тогда все (включая родительскую форму) может подписаться на это событие и получить подробности.

См. Следующий NotepadCode для примера:

class ParentForm
{
    private readonly ChildForm childForm;

    public ParentForm()
    {
        InitializeComponent();

        childForm = new ChildForm();

        childForm.SearchCompleted += childForm_SearchCompleted;
    }

    private void childForm_SearchCompleted(object sender, SearchCompletedEventArgs e)
    {
        // Update the display
        lblName.Text = e.DataToDisplay;
    }
}

class ChildForm
{
    public event EventHandler<SearchCompletedEventArgs> SearchCompleted;

    private void Search(string query)
    {
        // Do the searching

        OnSearchCompleted(new SearchCompletedEventArgs([arg values]));
    }

    public void OnSearchCompleted(SearchCompletedEventArgs args)
    {
        if (SearchCompleted != null)
        {
            SearchCompleted(this, args);
        }
    }
}
2 голосов
/ 01 апреля 2009

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

Итак, скажем, UpdateHUD - это метод в родительской форме, который выглядит примерно так:

private void UpdateHUD(string firstName, string lastName) {
    //...
}

Вы бы создали делегата с такой же подписью, как этот.

public delegate void HUDUpdateHandler(string firstName, string lastName);

Затем вы бы добавили параметр HUDUpdateHandler в конструктор дочерней формы и сохранили его в закрытом поле (например, this.handler = handler). Когда ваша дочерняя форма готова отправить свои данные обратно, вы вызываете частное поле дочерней формы (например, this.handler.Invoke(firstNameTextBox.Text, lastNameTextBox.Text)). Это вызовет UpdateHUD в вашем родительском классе, используя значения из дочернего класса, и вам не придется ничего выставлять.

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

2 голосов
/ 01 апреля 2009

В .NET формы являются объектами, как и все остальное, поэтому вы должны думать о проблеме в этих терминах.

При этом дочерней форме потребуется доступ к родительской форме. Вы можете обеспечить это, передав ссылку родительской формы на дочернюю форму через конструктор, метод или поле / свойство (хотя конструктор имеет наибольший смысл).

Затем вы можете изменить значения в родительской форме от дочернего.

ОДНАКО Я бы сказал, что это не лучшая идея. Скорее, дочерний элемент должен предоставлять событие, указывающее, что данные изменились (а также механизм получения этих данных), а затем родительский элемент должен подписаться на это событие и обновлять себя данными, когда они запускаются.

...