Problem mit dem WHS-Template

Eigener Bereich für die Entwickler unter uns! Add-Ins, aber auch andere Programme.
Antworten
sTunTe
Moderator
Beiträge: 3078
Registriert: 9. Jun 2008, 16:25
Wohnort: im nasskalten Norden

Problem mit dem WHS-Template

Beitrag von sTunTe »

Hallo Community.

Ich habe ein Problem mit dem WHS-Template.
Ich habe zwar Brendan Grant (WHS-Template) schon eine Mail und Martin (hier aus dem Forum ;) ) ein PN deswegen geschickt, aber bislang noch keine Antwort erhalten.
Nicht das ich ungeduldig bin, aber ich kann es einfach nicht ausstehen, wenn ich vor einem Problem stehe und die Lösung nicht parat habe... :twisted:
Außerdem bin ich grade so schön in Programmierlaune und würde ganz gerne weitermachen. :cry:

Zu meinem Problem:
Ich habe mir angewöhnt Funktionen, Subs, usw... in eigene Module auszulagern, um bei größeren Projekten die Übersicht zu wahren.
Bislang funktionierte diese Methode unter "normalen" Anwendungen auch immer einwandfrei.
Nur mit dem WHS-Template scheint das nicht zu gehen.... :?:

Mal ein Beispiel:
Gehen wir einmal davon aus, dass ich eine TextBox auf dem Form (MainTabUserControl) liegen habe.
Diese TextBox soll nun beim Laden des Addins mit einem Text gefüllt werden, wobei die Funktion (oder Sub) in einem seperatem Modul liegt.
Die Funktion rufe ich nun im Load-Ereignis des MainTabUserControls mit

Code: Alles auswählen

schreibeText()
auf.
Ok, soweit kein Problem.
Aber nun kommts:
Wenn ich nun in meinem Modul versuche die Textbox anzusprechen, wird mir diese vom Intellisense nicht angezeigt und zu allem Überfluss auch noch blau unterkringelt....

Ich habe mittlerweile keinen blassen Schimmer mehr wo der Fehler liegen könnte...
Es kann doch nicht sein, dass ich alles direkt ins "Hauptform" coden muss?!?

Hilfe!!!!!!!


Gruß
sTunTe
sTunTe
Moderator
Beiträge: 3078
Registriert: 9. Jun 2008, 16:25
Wohnort: im nasskalten Norden

Re: Problem mit dem WHS-Template

Beitrag von sTunTe »

So.

Ich habe mir jetzt einmal die Mühe gemacht und mir sämtliche Dateien des Templates genauer betrachtet.
Das o.g. Problem liegt darin, dass das MainTabUserControl als UserControl bzw. Klassenbibliothek und nicht als WindowsForm vorliegt.

So wie es aussieht, werden die Controls auf dem "Form" nicht freigegeben bzw. es fehlen die Verweise.
Dementsprechend bekomme ich auch die passende Fehlermeldung "Der Verweis auf einen nicht freigegebenen Member erfordert einen Objektverweis", wenn ich nun versuche auf eines der Controls aus einem Modul zuzugreifen.

Die Frage lautet also:
Wie erstelle ich nun die notwendigen Verweise?!?


Gruß
sTunTe
sTunTe
Moderator
Beiträge: 3078
Registriert: 9. Jun 2008, 16:25
Wohnort: im nasskalten Norden

Re: Problem mit dem WHS-Template

Beitrag von sTunTe »

Hier mal eine kleines Beispielprojekt für VB 2008.
Vielleicht weiß ja jemand Rat...

Gruß
sTunTe
Dateianhänge
Home Server Add-In1.zip
VB 2008 Projektdatei
(27.06 KiB) 173-mal heruntergeladen
BMelchert
Foren-Mitglied
Beiträge: 105
Registriert: 29. Jun 2009, 19:38

Re: Problem mit dem WHS-Template

Beitrag von BMelchert »

Hallo,

in C# löse ich das folgendermaßen:

Die mit dem Designer erzeugten Controls sind private, die gewünschten Controls also auf public setzen.
Beim Aufruf der Methode die Instanz mitgeben also DoSomething(this).
DoSomething(...) sieht dann so ähnlich aus:

Code: Alles auswählen

class Class1
{
  public void DoSomething(MainTabUserControl mt)
  {
    mt.listBox1.Items.Add("blafasel");
   }
[...]
Anstatt der Instanz kannst du natürlich gleich das gewünschte Control übergeben, spart dann auch die Umdeklaration.

cu,
Bernd
WHS: Acer H340 (6 TB)
sTunTe
Moderator
Beiträge: 3078
Registriert: 9. Jun 2008, 16:25
Wohnort: im nasskalten Norden

Re: Problem mit dem WHS-Template

Beitrag von sTunTe »

Hallo Bernd.

Um bei meiner Beispieldatei zu bleiben:
Durch

Code: Alles auswählen

Imports Microsoft.HomeServer.HomeServerConsoleTab.Home_Server_Add_In1.MainTabUserControl
werden mir zumindest schonmal die Controls in meinem Modul angezeigt.
Allerdings sind diese scheinbar immernoch auf private, so dass ich ihnen keine Werte zuweisen kann.

Ein Blick in die MainTabUserControl.Designer.vb verrät mir auch, dass alle Controls private sind.
Ein Ändern in public bringt leider garnichts.
Witzigerweise sieht die Designer.vb unter einer herkömmlichen Formsanwendung genauso aus.
Eine einzige Zeile unterscheidet sich.

Formsanwendung:

Code: Alles auswählen

Inherits System.Windows.Forms.Form
Klassenbibliothek:

Code: Alles auswählen

Inherits System.Windows.Forms.UserControl
Ein Ändern dieser Zeile ergibt lediglich ein neues "Outfit" (Titelleiste) des erstellten Forms...
Sonst nichts.

Zu Deinem Codesnippet:
Diese Idee hatte ich auch schon.
Da auf meinem Addin zur Zeit aber über 100 zu ändernde Controls liegen, mein Entwurf aus grob geschätzten 3500 Zeilen Code besteht und ich außerdem Threads einsetzen muss, wäre der "Mehraufwand" schlicht zu groß, bzw. unmöglich zu realisieren.
Außerdem würde mir die Übersicht verloren gehen... ;)

Irgendwo muss ich etwas übersehen haben...
Es kann doch nicht sein, dass man die Controls einer Klassenbibliothek nicht als public deklarieren kann?!?


Gruß
sTunTe
BMelchert
Foren-Mitglied
Beiträge: 105
Registriert: 29. Jun 2009, 19:38

Re: Problem mit dem WHS-Template

Beitrag von BMelchert »

Hallo,

dumme Frage: MainTabUserControl ist public?

cu,
Bernd
WHS: Acer H340 (6 TB)
BMelchert
Foren-Mitglied
Beiträge: 105
Registriert: 29. Jun 2009, 19:38

Re: Problem mit dem WHS-Template

Beitrag von BMelchert »

OK,

habe mir dein VB-Projekt kurz angeschaut. Du versuchst auf den Typ MainTabUserControl zuzugreifen,
wenn du das machst siehst du nur die vererbten Methoden von Usercontrol (das muss auch importiert werden,
nicht Forms). Du brauchst aber eine Referenz auf ein erzeugtes MainTabUserControl, in VB Me(?).

Warum nicht:

Code: Alles auswählen

Private Sub MainTabUserControl_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'TextBox1 beim Starten des Forms mit Text füllen.
        'siehe Sub in Module1.vb

        _schreibeText(Me)


    End Sub
und

Code: Alles auswählen

Module Module1

    Public Sub _schreibeText(MainTabUserControl mt)
        'Mit diesr Funktion soll eine Text in die Textbox geschrieben werden.
        'Da der Verweis zur TextBox1 fehlt, wird die Anweisung "unterkringelt" 

        mt.TextBox1.Text = "Hallo Welt"


    End Sub

End Module
TextBox1 natürlich public.
Syntax ungeprüft. Ich habe kein VB.

Oder verstehe ich dich vollkommen falsch?
cu,
Bernd
WHS: Acer H340 (6 TB)
sTunTe
Moderator
Beiträge: 3078
Registriert: 9. Jun 2008, 16:25
Wohnort: im nasskalten Norden

Re: Problem mit dem WHS-Template

Beitrag von sTunTe »

Hallo Bernd.

So ganz steige ich da noch immer nicht durch....
Bin aber Dank Deines Beispiels schon einen riesen Schritt weiter.

Code: Alles auswählen

    Private Sub MainTabUserControl_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'TextBox1 beim Starten des Forms mit Text füllen.
        'siehe Sub in Module1.vb

        _schreibeText(Me)

    End Sub
und

Code: Alles auswählen

Module Module1

    Public Sub _schreibeText(ByVal MainTabUserControl)

              MainTabUserControl.TextBox1.text = "Hallo Welt"

    End Sub

End Module
Somit lässt sich schonmal die Textbox befüllen.
Allerdings hat das Ganze noch einen kleinen Schönheitsfehler.
Intellisense funktioniert hier nicht bzw. nicht richtig.
Wenn ich versuche der TextBox1 (diese wird angezeigt) einen Wert zuzuweisen, bekomme ich wieder meine blauen Kringel mit o.g. Fehlermeldung.
Erst durch den Zusatz MainTabUserControl.TextBox1 kann ich den Text zuweisen.
Allerdings ohne Intellisense.
Damit könnte ich zwar leben, erschwert das Arbeiten aber beträchtlich.

Wo sind die VB-Götter, wenn man sie braucht?!? ;)

Gruß
sTunTe
BMelchert
Foren-Mitglied
Beiträge: 105
Registriert: 29. Jun 2009, 19:38

Re: Problem mit dem WHS-Template

Beitrag von BMelchert »

Hallo,
sTunTe hat geschrieben:

Code: Alles auswählen

Module Module1

    Public Sub _schreibeText(ByVal MainTabUserControl)

              MainTabUserControl.TextBox1.text = "Hallo Welt"

    End Sub

End Module
versuch mal:

Code: Alles auswählen

 Public Sub _schreibeText(ByVal mt as MainTabUserControl)

              mt.TextBox1.text = "Hallo Welt"

    End Sub
cu,
Bernd
WHS: Acer H340 (6 TB)
sTunTe
Moderator
Beiträge: 3078
Registriert: 9. Jun 2008, 16:25
Wohnort: im nasskalten Norden

Re: Problem mit dem WHS-Template

Beitrag von sTunTe »

Nicht schlecht!
Beide Daumen nach oben! Bild

Allerdings ist mir immernoch nicht klar, warum ich einer Sub in einer Formsanwendung nichts mitgeben muss, und bei einer Klassenbibliothek diesen (für meinen Geschmack) umständlichen Weg einschlagen muss. :?:
Vor allem, weil (vorausgesetzt das ich das richtig sehe Bild) die Instanziierung identisch abläuft....

Auf jeden Fall "Besten Dank" für die Mühe!


Gruß
sTunTe
Benutzeravatar
Martin
Moderator
Beiträge: 9948
Registriert: 11. Sep 2007, 10:51
Wohnort: Im wilden Süden

Re: Problem mit dem WHS-Template

Beitrag von Martin »

Hab den Thread erst jetzt gesehen.

Wenn du eine Methode (Sub) in einer Formsanwendung anlegst, ist das eine Klassenmethode der Hauptklasse, d.h. die sieht alle Elemente von innen heraus und kann darauf zugreifen (egal ob private oder public).
Wenn die Methode in einem anderen Modul ist, sieht die von der Formsklasse nur die Aussensicht, also die Public Elemente.

Anstelle der Übergabe des gesamten Controls mit allen public Elementen (bzw. dem Zwang diese public machen zu müssen) kannst du auch die schreibeText Methode so ändern, dass die immer nur ein einzelnes Element beschreibt, also eine Listbox oder ein Label usw.

Code: Alles auswählen

Private Sub MainTabUserControl_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'TextBox1 beim Starten des Forms mit Text füllen.
        'siehe Sub in Module1.vb
        _schreibeText(Textbox1)
    End Sub

Code: Alles auswählen

Public Sub _schreibeText(ByVal t as TextBox)
              t.Text = "Hallo Welt"
End Sub
Gruß
Martin
Essentials 2016 unter Windows Server 2022 auf HP Microserver Gen 8.
Entwickler von Lights-Out
BMelchert
Foren-Mitglied
Beiträge: 105
Registriert: 29. Jun 2009, 19:38

Re: Problem mit dem WHS-Template

Beitrag von BMelchert »

Hallo,
Martin hat geschrieben:Anstelle der Übergabe des gesamten Controls mit allen public Elementen (bzw. dem Zwang diese public machen zu müssen) kannst du auch die schreibeText Methode so ändern, dass die immer nur ein einzelnes Element beschreibt, also eine Listbox oder ein Label usw.
hatte ich im meinem ersten Beitrag auch schon vorgeschlagen, ist dann aber irgendwie untergegangen.

cu,
Bernd
WHS: Acer H340 (6 TB)
sTunTe
Moderator
Beiträge: 3078
Registriert: 9. Jun 2008, 16:25
Wohnort: im nasskalten Norden

Re: Problem mit dem WHS-Template

Beitrag von sTunTe »

Hallo Martin, hallo Bernd.
Martin hat geschrieben:Anstelle der Übergabe des gesamten Controls mit allen public Elementen (bzw. dem Zwang diese public machen zu müssen) kannst du auch die schreibeText Methode so ändern, dass die immer nur ein einzelnes Element beschreibt, also eine Listbox oder ein Label usw.
BMelchert hat geschrieben: hatte ich im meinem ersten Beitrag auch schon vorgeschlagen, ist dann aber irgendwie untergegangen.
Das ist nicht untergegangen, sondern in meinem Fall einfach ineffizient und unübersichtlich.
Ich zeig Euch mal warum.

Bild

Wie man sieht, werden die Tabs und die Labels für den Clientnamen dynamisch gesetzt.
Um an die Daten heranzugommen, müssen vor dem Anzeigen des Forms einige Funktionen abgearbeitet werden, die den Namen des Servers und die Namen der Clienten auslesen.

Wenn ich das nun so mache wie von Euch vorgeschlagen, würde das dann in etwa so aussehen:

Code: Alles auswählen

Private Sub MainTabUserControl_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
	_SucheNamenDesServers(Label1)
	_SucheNamenDesServers(Tab1)
	_SucheNamenDesErstenClienten(Label2)
	_SucheNamenDesErstenClienten(Tab2)
	_SucheNamenDesZweitenClienten(Label3)
	_SucheNamenDesZweitenClienten(Tab3)
oder

Code: Alles auswählen

Private Sub MainTabUserControl_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
	_SucheNamenDesServers(Label1, Tab1)
	_SucheNamenDesErstenClienten(Label2. Tab2)
	_SucheNamenDesZweitenClienten(Label3, Tab3)

Wenn ich das nun für alle Labels, Tabs, usw. machen würde, hätte ich weit über 100 Anweisungen und (was noch viel schlimmer wäre) entsprechend viele Subs/Module.

Daher ist die Methode mit der Übergabe des kompletten MainTabUserControls besser geeignet.
Hier kann ich das MainTabUserControl als "Inhaltsverzeichnis" missbrauchen und die eigentlichen Funktionen in die entsprechenden Module packen.
Was dann in etwa so aussieht:

Code: Alles auswählen

Private Sub MainTabUserControl_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
	
	'Home Server Name ermitteln
        _get_HomeServerName(Me)

	'Clienten ermitteln
        _initial_ClientNames(Me)

	...
	...
	...

End Sub

Code: Alles auswählen

Module get_HomeServerName

    Public Sub _get_HomeServerName(ByVal mt As MainTabUserControl)

	'Hier steht der Code um den Servernamen zu ermitteln.... ;)

	mt.Label1.Text = _HomeServerName
	mt.Tab1.Text = _HomeServerName

    End Sub

End Module
Funktioniert einwandfrei! ;)

Martin hat geschrieben:Hab den Thread erst jetzt gesehen.
Macht ja nichts.
Warum ich so ungeduldig war, habe ich oben ja schon geschrieben... ;)
Martin hat geschrieben:Wenn du eine Methode (Sub) in einer Formsanwendung anlegst, ist das eine Klassenmethode der Hauptklasse, d.h. die sieht alle Elemente von innen heraus und kann darauf zugreifen (egal ob private oder public).
Wenn die Methode in einem anderen Modul ist, sieht die von der Formsklasse nur die Aussensicht, also die Public Elemente.
Das ist soweit klar.
Es bleibt für mich aber weiterhin die Frage, warum sich Klassenbibliotheken (UserControls) so dermaßen von Formsanwendungen unterscheiden.
Schau Dir einfach mal das Beispielprojekt an, das ich oben angehängt habe.
Ich denke diese Frage werden mir aber nur die Jungs und Mädels von MS beantworten können... ;)
Da VS 2010 schon in den Startlöchern steht, gebe ich die Hoffnung nicht auf, dass MS hier ein bischen nachbessert und das Ganze einheitlich macht.
Wir werden sehen... ;)


Gruß
sTunTe
Antworten