2009-02-19 5 views
4

У меня есть простая контактная книга. Приложение имеет главное окно, которое является формой mdi. Когда контакт добавляется с помощью формы «добавить контакт», я хочу показать простое сообщение обратной связи в строке состояния родительского окна, в котором говорится, что контакт был успешно добавлен.Проходящая стоимость от ребенка до родителя mdi в VB.net

Вот ребенок загрузка:

Private Sub addButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles addButton.Click 
    Dim af As New addForm 
    af.MdiParent = Me 
    af.Show() 
End Sub 

Проблема заключается в том, что, поскольку родитель на самом деле является МДИ родителем, и «добавить контакт» форма запускается с .Show() вместо .ShowDialog(), я не могу хранить любое возвращаемое значение, которое может быть использовано стартовым Sub для выполнения действия.

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

Private Sub addButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles addButton.Click 

    Dim contact = <contact> 
         <quickName><%= quickNameTextBox.Text %></quickName> 
         <firstName><%= firstNameTextBox.Text %></firstName> 
         <lastName><%= lastNameTextBox.Text %></lastName> 
         <email><%= emailTextBox.Text %></email> 
         <website><%= websiteTextBox.Text %></website> 
         <telephone><%= telephoneTextBox.Text %></telephone> 
         <mobile><%= mobileTextBox.Text %></mobile> 
        </contact> 

    Dim contactList = XDocument.Load("contactList.xml") 

    contactList.Elements()(0).Add(contact) 
    contactList.Save("contactList.xml") 
    //something here to trigger the status update in the parent? 
    //trivia: SO doesn't support VB single-quote comments... 
    Me.Close() 

End Sub 

P.S. Видимо, я довольно плохо отношусь к вещам ... поэтому любой желающий повторить этот вопрос приветствуется.

ответ

6

Способ, которым я бы справился с этим, заключается в создании пользовательского события на дочернем элементе управления. Затем обработайте событие на родительском элементе управления.

Во-первых, определить событие в дочерний элемент управления (например, определить свои собственные):

Public Event EVENTNAME(ByVal sender as Object, ByVal ValueToReturn As String) 

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

RaiseEvent EVENTNAME(Me, txtBoxWithReturnValue.Text) 

Как только вы это сделаете, теперь в родительской форме вы можете обрабатывать настраиваемое событие. Чтобы сделать это, вам нужно добавить слушатель, чтобы «слушать» для случая, когда он стреляет:

AddHandler CONTROLNAME.EVENTNAME, AddressOf EVENTNAME 

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

Private Sub FUNCTIONAME(ByVal sender As System.Object, ByVal ValueToReturn as String) Handles CONTROLNAME.EVENTNAME 

'Code to handle data here 

End Sub 
+0

Извините, но где в родительской форме я помещаю обработчик? К чему относится CONTROLNAME? – Mussnoon

+0

Вы должны поместить обработчик сразу после создания дочерней формы. Это похоже на этот пост: http://stackoverflow.com/questions/1774386/how-to-declare-events-on-class-library-dll-and-catch-them-on-form/1775453#1775453 – Walter

0

Создайте класс контроллера в MDI и передайте его как параметр дочерней форме. Когда перед Me.Close() назначьте контактный список для свойства на контроллере.

Вам необходимо разделить ваши данные и графический интерфейс больше. Для получения дополнительной информации о шаблоне Model-View-Controller перейдите по адресу here.

0

Ответ Джона - хотя и весьма полезный - является неполным. И недостающая часть может вызвать путаницу для новичков, подобных мне.

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

Private WithEvents oneAddForm As New addForm //create a new instance of addForm 

Private Sub addButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles addButton.Click 
    oneAddForm.MdiParent = Me 
    oneAddForm.Show() 
End Sub 
//using this instance to load the form... 

Private Sub updateStatus(ByVal sender As System.Object, ByVal contactName As String) Handles oneAddForm.addSuccess 
    statusLabel.Text = contactName & " has been added to your contact list." 
End Sub 
//...and to put in the event handler 

Но это приводит к «не может получить доступ к объекту ... расположенную» исключение при попытке загрузить форму oneAddForm после закрытия его один раз.

0

В VB.NET вы можете использовать [Мои] пространства имен. My.Forms. [Имя вашей формы MDI], поэтому ... если ваша основная форма была вызвана MdiMain, вы могли бы сделать что-то подобное.

My.Forms.MdiMain.lblStatus = "X" 

Все мои дочерние формы наследовать тот же базовый класс, и этот класс только имеет свойство, которое возвращает My.Forms.MdiMain. Я назвал его MdiParentForm. Таким образом, я могу просто сказать «Me.MdiParentForm» в любой форме и bam ... thats parent. (Менее типизация)

1

Это самый простой ответ, никаких событий!

Ситуация: 1 MdiParent form (Form1) и 2 дочерние формы управления (Control1Form и Control2Form). При запуске в MdiParent создаются дочерние элементы управления (control1 и control2).

Форма 1 имеет метку в StatusStrip с именем StatusLabel. Control2 имеет кнопку с именем Button1

Цели: Когда кнопка Control2 в щелчке Control2 пишет на звание Control1 и к StatusLabel из Form1

PARTIAL CODE 

FORM1 
Public Class Form1 
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
control1 = New Control1Form 
control2 = New Control2Form 
control1.MdiParent = Me 
control1.Show() 
control2.MdiParent = Me 
control2.Show() 
End Sub 
End Class 


CONTROL2FORM 
Public Class Control2Form 
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click 
'Title of Control1 
CType(Me.ParentForm, Form1).control1.Text = "Title bar text" 
'Status Strip Label 
CType(Me.ParentForm, Form1).StatusLabel.Text = "Status Strip Text" 
End Sub 
End Class 

И вуаля! Надеюсь, это поможет

-1

Я хотел бы добавить немного другой ответ, который работал для меня просто отлично.

Следующее из приведенного выше ответа отлично подойдет для меня, пока я делал какие-либо изменения кода в родительском MDI. Когда я застрял эквивалент form1.MDIparent = меня, все провалилось. Поэтому я оставил этот шаг.

Ниже приведенная форма 1 должна быть именем родительской формы MDI, которую вы используете. Затем он работает в моей среде, просто отлично подходит для перехода к переменным родителям или перехода к другим функциям родителя.

Прежде чем это сделать, у меня возникла проблема с дочерним процессом, вызывающим другого родителя, у которого были все пустые поля!

CType(Me.ParentForm, Form1).control1.Text = "Title bar text" 
'Status Strip Label 
CType(Me.ParentForm, Form1).StatusLabel.Text = "Status Strip Text" 

CType(Me.parentForm, Form1).variableDefinedinParentString = "abc" 'passing a variable 

CType(Me.parentForm, Form1).subroutineLOCATEDinPARENT() 'Calling a subroutine in the parent 

Возможно, это поможет некоторым другим. Я надеюсь, что это так!