Panel aus Form1 in Form2 'life' anzeigen (clonen)

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von vb_fan.

    Panel aus Form1 in Form2 'life' anzeigen (clonen)

    Hallo Leuts...
    Programmiere immer noch an meiner Schulungs-/Präsentationssoftware für die Sportbootführerscheinausbildung. Nach dem ersten Einsatz im Seminar (arbeite dort mit Beamer und der Standard-Windows Funktion: Display Clone) überlege ich, ob ich nicht einen 'echten' Präsentationsmodus (ähnlich wie in PowerPoint) realisiere bzw. frage mich, wie man das möglichst einfach realisieren kann (kompliziert und aufwändig bekomme ich das vermutlich selbst hin). Ggf. gibt es ja in VB.net bzw. der Framework schon simple Standards, die man nutzen kann.

    Zum Programm: In einem Panel (nenne es mal 'pPräsentation') spielt sich alles ab, was die Seminarteilnehmer sehen müssen/sollen. In meinem eigentlichen Programmfenster gibt es nun natürlich noch x-weitere Panels und Controls, in denen die für den Referenten wichtigen Dinge wie Aufgabenstellungen, Lösungen, methodisch/didaktischen Hinweise dargestellt sind bzw. die die notwendigen Werkzeugtools enthalten.

    Das 'pPräsentation' enthält primär eine PictureBox, die die Seekarte aufnimmt. Des weiteren 'zeichne' ich - quasi als Lerninhalt - mittels LineShapes, Ovalshapes Objekte (in einem ShapeContainer) mittels Maussteurung ein. Teilweise gebe ich auch Text (beliebig rotiert) direkt mittels Graphics auf das Bitmap aus (das Bitmap jeweils nach dem Neuzeichnen an das Panel im zweiten Fenster auszugeben, ist sicherlich keine Herausforderung).

    Und alles, was ich nun in dem Panel 'pPräsentation' mache, würde ich gerne zeitgleich in einem zweiten Fenster - welches dann über den Beamer geht - darstellen. Mir geht es konkret darum, dass, wenn ich in meinem Referentenfenster z.B. mit der Maus eine Kurslinie 'aufziehe', dieses parallel im zweiten Fenster dargestellt wird.

    Ergänzend muss sollte ich vielleicht noch anmerken, dass das Panel 'pPräsentation' über Laufleisten verfügt, da die Seekarte deutlich größer ist, als die pysikalische Größe des sichbaren Fensters. Das heißt, auch der Panelausschnitt muss jeweils synchronisiert angezeigt werden.

    Gibt es etwas Simples als Lösungsansatz?

    Danke für euer Feedback

    lg
    Charly

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „PrinzCharly“ ()

    PrinzCharly schrieb:

    Lösungsansatz
    Probiere mal, das Panel der anderen Form zuzuweisen, indem Du es der Controls-Collection der anderen Form zuweist:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private dlg As Form2
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. If dlg Is Nothing OrElse dlg.IsDisposed Then
    5. dlg = New Form2 ' Instanz der 2. Form erzeugen
    6. End If
    7. If Not dlg.Visible Then
    8. dlg.Show() ' nicht modal anzeigen
    9. End If
    10. dlg.GetControl(Me.Panel1) ' Panel übertragen
    11. End Sub
    12. End Class

    VB.NET-Quellcode

    1. Public Class Form2
    2. Public Sub GetControl(ctrl As Control)
    3. Me.Controls.Add(ctrl)
    4. End Sub
    5. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    PrinzCharly schrieb:

    Kopie
    Dann musst Du es clonen. Gugst Du hier.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    geht nicht.
    Controls sind halt Unikate - jedes wird nur ein einziges mal angezeigt.

    Was denkbar wäre ist OwnerDrawing - das ist performant, Stand der Technik - allerdings muss man dafür ziemlich sattelfest sein in OOP-Programmierung: Events, Vererbung, Generica, Listen etc..

    Etwas einfacher wäre, ständig eine Bitmap neu zu bemalen. Eine Bitmap ist ja kein Control, und kann also auch in mehreren Panels als BackgroundImage erscheinen.

    ErfinderDesRades schrieb:

    geht nicht.
    Controls sind halt Unikate - jedes wird nur ein einziges mal angezeigt.


    Scheint wohl so zu sein. Das Verschieben geht ohne Probleme, aber brauche halt eine parallele Kopie.
    Werde dann doch wohl handwerklich vorgehen und schauen, was ich realisieren kann. Das mit der Bitmap als Hintergrund hatte ich schon realisiert. Geht mir darum, das wenn ich neue Kurslinien im Referentenfenster einzeichne, dass das der Teilnehmer auf dem Beamer eben auch sehen kann. Mal schauen, wie ich in meiner Form1 und Form2 das gleichzeitig machen kann. Geht bestimmt; ist halt ein bissl Programierarbeit gefragt. Wollte mir es einfach machen - wenn es ein solche Lösung gegeben hätte.

    Danke euch beiden...

    PrinzCharly schrieb:

    wenn ich neue Kurslinien im Referentenfenster einzeichne, dass das der Teilnehmer auf dem Beamer eben auch sehen kann.
    Wozu brauchst Du da 2 Fenster?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    PrinzCharly schrieb:

    ist halt ein bissl Programierarbeit gefragt.
    wie gesagt: Es ist mehr als ein "bischen Programmier-Arbeit".

    Zunächst mal musst du wirklich OOP programmieren können - bei den in post#5 genannten Punkten habich vergessen, dass du natürlich auch eigene Klassen anlegen können must, instanzieren, in Listen zufüge und so Krams.
    Denn du musst ein Datenmodell deiner Zeichnung erschaffen.
    Also ein System von DatenObjekten, aus dem sich das Gesamtbild neu erstellen lässt.
    Alternativ kannste auch immer fröhlich in die Bitmap krikeln, blos wenn du dich vermalt hast, musste von vorn anfangen, denn einmal eingezeichnete Pixel kann man von einer Bitmap nicht wieder zurücksetzen, wie sie vorher waren.
    Und überhaupt musste dir eine Eingabe für deine Zeichnungen überlegen.

    Also ich hab mal was mit Zeichnungs-Objekten gemacht: allgemeine Zugriffs-Lösung für: MySql, Access, SqlCe, SqlServer, DatasetOnly
    Das fokussiert nun mehr darauf, Zeichnungen auch abspeicherbar zu haben, aber so in die Richtung könnte es laufen (stell dir halt vor, es gäbe noch ein Hintergrundbild dazu).
    zu 'RodFromGermany'
    2 Fenster deshalb, weil ich die Linie mit Blick auf mein Notebook in meiner 'Referentenkarte' einzeichne, in Abhängigkeit der Aufgabenstellung und der richtigen Lösung. Muss in einer Toolbox dazu gewissen Einstellungen (Linienfarbe, -art, -breite, ...) vornehmen. Braucht der Teilnehmer nicht zu sehen.
    Sehen hingegen muss er aber, wo die Kurslinie ansetzt und wo sie endet. Hinweis: Die Teilnehmer erarbeiten diese Lösungen parallel auf einer traditionellen Papierkarte mit.

    zu 'ErfinderDesRades'
    Wird wohl auf eine rein zeichnerische Lösung hinauslaufen - also in der Bitmap. In vergangenen Fragen/Themen zu meinem Projekt habe ich ja schon darauf hingewiesen, dass ich das Original der Seekarte im Speicher halte und jedes Mal auf einer Kopie zeichne. Die 'Objekte' die ich dabei erzeuge werden mit allen notwendigen Angaben (Linienfarbe, -art, -breite, ...) mit der Erstellung in einer Datenbank gespeichert. Aus dieser Datenbank heraus werden sie dann auch gezeichnet. 'Fehler' lassen sich somit korrigieren. Das was ich bis jetzt als 'LinieShape' erzeugt habe, wir nun halt eine Linie mit Graphics. Kein großer Programmieraufwand, da die Datenbasis für die Objekte ja in der Datenbank liegen.
    ja denn - wenn du das Zeichnen und Kram alles schon fertig hast (kein großer Programmieraufwand?) - also eine Bitmap zu klonen und in einem anneren Form als HintergrundBild anzugeben ist kein Problem - ist nur eine Zeile:

    VB.NET-Quellcode

    1. myPresentationForm.Panel1.BackgroundImage = new Bitmap(myBitmap)
    Mit Disposen sinds dann nochmal paar Zeilen - da wäre ja die vorherige myBitmap zu disposen, und ihr Klon ebenfalls.
    Aber vielleicht habt ihr beiden - oder jemand anders - doch noch einen Vorschlag für mich.
    Mit folgendem Code zeichne ich beispielsweise einen Kreis/Oval in mein 'Kartenpanel'.

    VB.NET-Quellcode

    1. Dim _sc As New ShapeContainer
    2. Dim _scP As New ShapeContainer
    3. _sc.Parent = pbZF ' ShapeContainer dem Bild (PictureBox) 'pbZF' zuordnen (im Referentenfenster)
    4. _scP.Parent = frmPräsentation.ppbZF ' Shapecontainer dem Bild (PictureBox) 'ppbZF' zuordnen (im Präsentationsfenster)


    VB.NET-Quellcode

    1. _oval = New OvalShape
    2. _oval.Parent = _sc
    3. _oval.Name = CType(_dr("ID"), String)
    4. _oval.BorderWidth = CInt(_dr("LinieBreite"))
    5. _oval.BorderStyle = CType(_dr("LinieStyle"), DashStyle)
    6. _oval.BorderColor = _col
    7. _oval.Top = intPKurs1.Y
    8. _oval.Left = intPKurs1.X
    9. _oval.Height = intPKurs2.Y
    10. _oval.Width = intPKurs2.X
    11. _oval.Tag = _sBezeichnung
    12. _oval.Enabled = False
    13. _oval.Visible = True
    14. _sc.Shapes.Add(_oval)


    Nun wollte ich den Code - mit meinem 'Anfängerwissen' - simpel wie folgt ergänzen...

    VB.NET-Quellcode

    1. Dim _ovalK = New OvalShape
    2. _ovalK = _oval
    3. _ovalK.Parent = _scP
    4. _scP.Shapes.Add(_ovalK)


    Leider wird das Oval nun nur noch im Präsentationsfenster gezeichnet. Kommentiere ich die 4 Zeile aus, wird wieder im Referentenfenster gezeichnet. Warum?
    Shape, ShapeContainer, OvalShape kenn ich alle nicht. Klingt mir nach dem "PowerPack", eine MS-ZusatzBibliothek, die sich leider oft durch Instabilität und Portiblitätsprobleme hervortut.

    Und es sind alles Controls - das ist also kein Zeichnen, sondern dynamisches Zufügen von Controls.

    Jo, und das hatten wir ja schon: Ein Control kann nur an einer Stelle angezeigt werden, nicht auf 2 Forms gleichzeitig.
    Also sowas wie "Referenz-Form / Präsentation-Form" ist mit diesem Ansatz zunächstmal nicht möglich.
    Du müsstest halt was zusammenkrepeln, was die Shapes deines Ref-Forms iwie ausliest, und analog dazu auffm Präs-Form ebenfalls solche Shapes zufügt.
    jo... Kommen aus dem 'PowerPack'. Für meine Bedürfnisse hier aber durchaus zu gebrauchen. Probleme damit habe ich (bis jetzt) noch nicht. Für mich habe die Linien beispielsweise den Charme, dass ich auf eine Position in meiner Seekarte klicken kann und dann, mit gedrückter Maustaste, den Punkt auswählen kann, wo die Linie enden soll. Dabei wird die Linie eben dynamisch angezeigt, also das Linienende dem Mauszeiger folgt.... (habe bisher nicht versucht, ob und wie das ggf. auch mit Graphics geht).

    Aber noch mal zu dem:

    ErfinderDesRades schrieb:

    Ein Control kann nur einmal angezeigt werden


    Aber nochmals zu oben: mit

    Quellcode

    1. Dim _ovalK = New OvalShape
    erstelle ich doch ein neues 'Objekt'?!

    Habe jetzt die 4 Zeilen wie folgt geändert:

    VB.NET-Quellcode

    1. Dim _ovalK = New OvalShape
    2. _ovalK.Parent = _scP
    3. _ovalK.Name = CType(_dr("ID"), String)
    4. _ovalK.BorderWidth = CInt(_dr("LinieBreite"))
    5. _ovalK.BorderStyle = CType(_dr("LinieStyle"), DashStyle)
    6. _ovalK.BorderColor = _col
    7. _ovalK.Top = intPKurs1.Y
    8. _ovalK.Left = intPKurs1.X
    9. _ovalK.Height = intPKurs2.Y
    10. _ovalK.Width = intPKurs2.X
    11. _ovalK.Tag = _sBezeichnung
    12. _ovalK.Enabled = False
    13. _ovalK.Visible = True
    14. _scP.Shapes.Add(_ovalK)


    Jetzt funktioniert - selbstverständlich. Aber, wo liegt denn nun formal der Unterschied zu meinem '4-Zeiler' oben?
    guck doch hin:

    VB.NET-Quellcode

    1. Dim _ovalK = New OvalShape
    2. _ovalK = _oval
    3. _ovalK.Parent = _scP
    4. _scP.Shapes.Add(_ovalK)
    zeile#1: ein neues OvalShape wird an _ovalK zugewiesen
    #2: ein Dingens namens _oval wird an _ovalK zugewiesen. Jetzt ist das neue OvalShape von eben natürlich nicht mehr darin.
    #3, #4 betreffen jetzt das Dingens, was in _ovalK und _oval ist - es ist ja dasselbe Objekt, vermutlich auch ein OvalShape, aber halt kein neues, sondern dasjenige, was vorher schon in _oval war.
    Hmm... Habe meine Code wie folgt verstanden:
    Neues Objekt _ovalK. Dem ordne ich mit _ovalK = _oval alle Eigenschaften von _oval zu. Damit hätte ich also eine Kopie von _oval erstellt.
    Wie kopiere ich denn ein vorhandenes Control (z.B. Label) mit all seinen Eigenschaften, um es an einer zweiten Stelle auf einer Form darzustellen?

    jo... Habe nochmals google befragt. Scheint wohl so zu sein, dass das so nicht geht. Habe mir noch nie dazu Gedanken gemacht - also vermutlich in der Form auch noch nie benötigt...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „PrinzCharly“ ()

    Eddy schrieb:

    den DC hohlen
    Nicht hohl. ;)
    Das musst Du säuberlich trennen.
    Es gibt flache Clones und es gibt tiefe Clones. Da werden Dateninhalte übertragen, keine GUI-Darstellung.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()