System.Reflection i dynamiczne ładowanie kontrolki

0

Witam. Mam problem z dynamicznym ładowaniem kontrolki. Program buduję w Windows Forms i po kliknięciu na dany button, chciałbym żeby była ładowana inna kontrolka dynamicznie.
Czytałem trochę na ten temat, ale dalej mi nie wychodzi. Próbowałem m.in w taki sposób:

var a = Assembly.LoadFile("AddBook.dll");
var obj = a.CreateInstance("AddBook");
form.Controls.Add(obj);

ale kompilator wypluwa mi błąd. Cannot convert object to windows forms.

Będę bardzo wdzięczny za pomoc.

Dodam że kontrolki, które chcę ładować są wszystkie typu UserControl. Pozdrawiam

0

No to najprościej chyba będzie rzutować sobie object na usercontrolkę, np. tak:

form.Controls.Add(obj as UserControl);

0

Dzięki za pomoc. Kod się teraz kompiluje, ale kontrolka nie pojawia się na formie. Czy to dlatego, że nie przypisuję jej konkretnej lokalizacji, czy z innego powodu ? Jeżeli tak to w jaki sposób mogę jej przypisać to lokalizację ?

0
var a = Assembly.LoadFile("AddBook.dll");
var obj = a.CreateInstance("AddBook") as Control;
if(obj == null) 
   MessageBox::Show("lipa, AddBook nie istnieje lub nie jest kontrolką");
else
{
   obj.Location = new Point(100, 100);
   form.Controls.Add(obj);
}
0

Odswieżam temat. Mam podobny problem, a dokładniej wykonuje powyższy kod i dll-ka się nie ładuje, a dokładnej obj = null. Nie wiem dlaczego tak się dzieje, tym bardziej że do zmiennej a faktycznie "coś się" załadowało. Proszę o pomoc

0

w CreateInstance wymagane jest podanie Type.FullName http://msdn.microsoft.com/en-us/library/system.type.fullname.aspx

sprobuj podac nie tylko nazwe typu, ale caly namespace

0

Zrobiłem tak jak mi doradziłeś i wyrzeźbiłem coś takiego:

var a = Assembly.LoadFile("AddBook.dll");
                Type t = typeof(a);   // tutaj kompilator wywala błąd
                var obj = a.CreateInstance(t.FullName) as Control;
              
                if(obj == null)
                 MessageBox.Show("lipa, AddBook nie istnieje lub nie jest kontrolką");
                else
                    {
                        obj.Location = new Point(100, 100);
                        form.Controls.Add(obj);
                    }

Treść błędu:
Error 1 The type or namespace name 'a' could not be found (are you missing a using directive or an assembly reference?)

Próbowałem kombinować właśnie z dodaniem dyrektywy using ale nic z tego nie wyszło.

0

Zaczęli używać 'var' i zapomnieli co jakie typy zwraca...

LoadFile zwraca Assembly. Później odczytujesz typ tego, więc dostajesz typ Assembly. Potem próbujesz stworzyć instancję typu Assembly. No.. tak się nie da.

Jeżeli nie znasz fullname swojej kontrolki (np. "AddBook.AddBook") to pobierz typy ze swojego assembly (metoda GetTypes o ile pamiętam i sprawdź, który z tych typów dziedziczy po Control).

np. w jednym z moich programów wygląda to tak:

this.mailClients.Clear();
string[] componentFiles = Directory.GetFiles(componentsDirectory, "*.dll");

for(int i = 0; i < componentFiles.Length; i++)
{
    Assembly componentAssembly = Assembly.LoadFile(componentFiles[i]);
    Type[] componentTypes = componentAssembly.GetTypes();
    foreach (Type componentType in componentTypes)
    {
        if (typeof(MoorHunt.MailClient).IsAssignableFrom(componentType))
        {
            this.mailClients.Add(Activator.CreateInstance(componentType) as MoorHunt.MailClient);
        }
    }

    int progressPercentage = 100 * (i + 1) / componentFiles.Length;

    LoadComponentsProgressChangedEventArgs eArgs = new LoadComponentsProgressChangedEventArgs(
        progressPercentage, new FileInfo(componentFiles[i]).Name, null);
    async.Post(delegate(object e)
        {
            OnLoadComponentsProgressChanged(e as LoadComponentsProgressChangedEventArgs);
        }, eArgs);
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1