2014-10-15 3 views
0

На каждое событие DataGridView1_SelectionChanged Мне нужно запустить Private Sub OnSelectionChanged() формы, загруженной в Panel1 (см. Изображение http://tinypic.com/r/2nu2wx/8).Как вызвать Sub, не зная, какая форма загружена в панель?

Каждая форма, которая может быть загружена в Panel1, имеет тот же Private Sub OnSelectionChanged(), который инициирует все необходимые вычисления. Например, я могу загрузить форму, которая вычисляет температуры, или я могу загрузить форму, которая вычисляет напряжения. Если в DataGridView1 основной формы выбран другой элемент, следует пересчитать либо температуры, либо напряжения.

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

В настоящее время я использую Shared Event:

'Main form (Form1). 
Shared Event event_UpdateLoadedForm(ByVal frm_name As String) 

'This is how I load forms into a panel (in this case frm_SCT). 
Private Sub mnu_SCT_Click(sender As Object, e As EventArgs) Handles mnu_SCT.Click 
    frm_SCT.TopLevel = False 
    frm_SCT.Dock = DockStyle.Fill 
    Panel1.Controls.Add(frm_SCT) 
    frm_SCT.Show() 
    Var._loadedForm = frm_SCT.Name 
    RaiseEvent event_UpdateLoadedForm(Var._loadedForm) 
End Sub 

‘Form that is loaded into panel (Form2 or Form3 or Form4...). 
Private WithEvents myEvent As New Form1 

Private Sub OnEvent(ByVal frm_name As String) Handles myEvent.event_UpdateLoadedForm 
    ‘Avoid executing code for the form that is not loaded. 
    If frm_name <> Me.Name Then Exit Sub 
End Sub 

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

Public Event MyEvent As EventHandler 

Protected Overridable Sub OnChange(e As EventArgs) 
    RaiseEvent MyEvent(Me, e) 
End Sub 

Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) _ 
    Handles DataGridView1.SelectionChanged 
    OnChange(EventArgs.Empty) 
End Sub 

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

спасибо.

+1

У вас есть контракт, каждый класс, производный от формы, должен предоставить метод OnSelectionChanged. Вы выполняете контракт, написав интерфейс. И каждый класс формы реализует его. Теперь это просто. –

+0

Это казалось очень логичным подходом, и я уже пробовал это. Чтобы протестировать его, я создал интерфейс MyInterface.vb только с одной строкой: Sub ShowMessageBox(). Каждая форма, которая реализовала этот интерфейс, должна иметь такую ​​подпрограмму. Все идет нормально. Но я все еще не мог понять, как запустить эту подпрограмму из события DataGridView_SelectionChanged (DataGridView находится в основной форме). Не могли бы вы показать простой псевдокод, как это сделать? Спасибо. – Inrush

+0

Передайте объект формы в тип интерфейса с помощью DirectCast. Или TryCast, если вы хотите гибко. Ваша переменная, отслеживающая все, что загружается на панели, должна быть либо типа Form, либо типа интерфейса. Не забудьте оставить замененные формы. –

ответ

0

Принимая во внимание комментарии Ханса Пассанта, а также код, который он опубликовал в соответствующей теме, я достиг того, что хотел (см. Код ниже).

Public Interface IOnEvent 
    Sub OnSelectionChange() 
End Interface 

Public Class Form1  
    ' ??? 
    Private myInterface As IOnEvent = Nothing 

    ' Create and load form. 
    Private Sub DisplayForm(frm_Name As String) 

     ' Exit if the form is already displayed. 
     If Panel1.Controls.Count > 0 AndAlso _ 
      Panel1.Controls(0).GetType().Name = frm_Name Then Exit Sub 

     ' Dispose previous form. 
     Do While Panel1.Controls.Count > 0 
      Panel1.Controls(0).Dispose() 
     Loop 

     ' Create form by its full name. 
     Dim T As Type = Type.GetType("Namespace." & frm_Name) 
     Dim frm As Form = CType(Activator.CreateInstance(T), Form) 

     ' Load form into the panel. 
     frm.TopLevel = False 
     frm.Visible = True 
     frm.Dock = DockStyle.Fill 
     Panel1.Controls.Add(frm) 

     ' ??? 
     myInterface = DirectCast(frm, IOnEvent) 

    End Sub 

    Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) _ 
     Handles DataGridView1.SelectionChanged 

     ' Avoid error if the panel is empty. 
     If myInterface Is Nothing Then Return 

     ' Run subroutine in the loaded form. 
     myInterface.OnSelectionChange() 

    End Sub 
End Class 

Одна последняя вещь - это было бы здорово, если бы кто-то мог бы взять быстрый взгляд на код (он работает) и убедитесь, что это нормально, особенно строки, помеченные «???» (Я не» пока не пойму их).

Смежные вопросы