2015-12-27 2 views
1

Как создать ссылку на форму, просто по ее имени или .Fullname ..? Это кажется таким простым, но ничего, что я пробовал, будет работать.Перечислить все формы в проекте VB.NET, а затем показать их по имени или по имени?

Учитывая следующий код, часть в конце - это место, где я застрял.

Спасибо.

Public Class frmLauncher 

Private Sub FormPicker_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

    Dim myAssembly As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly() 
    Dim myTypes() As Type = Nothing 

    ' Both of the following lines seem to do the same thing. 
    ' Is one way better or safer than the other? 
    myTypes = myAssembly.DefinedTypes 
    myTypes = myAssembly.GetTypes 

    For Each t In myTypes 
     If t.BaseType.FullName.ToString.ToUpper = "System.Windows.Forms.Form".ToUpper Then 
      ListBox1.Items.Add(t.Name) 
     End If 
    Next 

End Sub 

Private Sub ListBox1_DoubleClick(sender As Object, e As EventArgs) Handles ListBox1.DoubleClick 

    Dim frmName As String = ListBox1.Text 

    ' the next line is where I'm totally stuck. 
    Dim frm As Form = GetSomethingUnknown(frmName) 

    frm.Show() 

End Sub 

End Class 
+0

Форма - это просто класс, поэтому вы не могли бы и не могли бы создать ссылку на него, но вы могли бы создать ссылку на экземпляр (объект), созданный из этого класса. Я бы держался подальше от Reflection. Во-первых, это довольно сложно, и вы не хотите рисковать тем, что это похоже на решение любой ситуации, с которой вы сталкиваетесь. – Plutonix

+0

Как только у меня появился список форм, я просто использовал список для генерации кода для загрузки форм - ОК для быстрого и грязного, а не динамического. Ищите NimbleText для интересного инструмента для создания повторяющегося кода. – rheitzman

ответ

1

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

For Each t In myTypes 
    If t.BaseType.FullName.ToString.ToUpper = "System.Windows.Forms.Form".ToUpper Then 
     ListBox1.Items.Add(t.FullName) 
    End If 
Next 

Теперь код, необходимый для создания экземпляра состоит в следующем

Private Sub ListBox1_DoubleClick(sender As Object, e As EventArgs) Handles ListBox1.DoubleClick 

    Dim frmName As String = ListBox1.Text 

    Dim myAssembly As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly() 
    Dim obj = myAssembly.GetType(frmName).InvokeMember(Nothing, Reflection.BindingFlags.CreateInstance, Nothing, Nothing, Nothing) 
    Dim frm As Form = CType(obj, System.Windows.Forms.Form) 
    frm.Show() 
End Sub 

Как вы можете видеть, решающим моментом здесь является call to InvokeMember метод из т ype, идентифицированный вашей переменной frmName. Это сложный метод, который вы должны тщательно изучить, если хотите действительно работать с кодом отражения.

+0

Спасибо. Это работает отлично. Как я уже сказал, я предполагал, что это должно произойти, например, GetMethod и т. Д., Но я понятия не имел, что. Я искал InvokeMember и да ... У меня еще есть чему поучиться. Я собираюсь положить некоторые Breakpoints и нос вокруг. У меня есть вопросы, связанные с последующим ... 1) В VBA тип «Вариант» - это все для всех. Это как «obj» работает в этом случае? Тип не определен. 2) Какая из этих строк кода из моего примера предпочтительнее? myTypes = myAssembly.DefinedTypes myTypes = myAssembly.GetTypes – spinjector

+0

Извините, я вижу, что редактор HTML не форматировал какой-либо из моих комментариев выше. Надеюсь, вы справитесь. Благодаря..!! – spinjector

+0

DefinedTypes - это IEnumerable , а GetTypes возвращает массив типов. Существует разница между двумя. Первый, являющийся IEnumerable, позволяет сразу начать цикл, второй требует, чтобы он дождался завершения сборки всего массива в памяти. В вашем контексте DefinedTypes лучше, но если это создатель сделки, зависит от того, сколько типов присутствует в сборке. Object vs Variant, я не эксперт в этом вопросе, но пока они не совсем то же самое, для задач общего назначения, я думаю, вы могли бы оборудовать два – Steve

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