Autor
|
Thema: VB.NET: SplitContainer- Splitter sichtbar machen (3080 / mal gelesen)
|
KMassler Ehrenmitglied V.I.P. h.c. CAD Admin + Mädchen für Alles...
Beiträge: 2657 Registriert: 06.11.2000
|
erstellt am: 30. Aug. 2017 12:55 <-- editieren / zitieren --> Unities abgeben:
Hallo Freunde, ich hoffe, jemand hat einen Tipp für mich: Ich verwende ganz gerne "SplitContainer" bei Progrämmchen mit mehreren Bereichen. Allerdings gefällt mir hier gar nicht, dass der Splitter normalerweise nicht sichtbar ist. Anwender, die nicht wissen, dass die Fenster hier ziehbar sind, haben also keinen Nutzen davon- außer sie bemerken zufällig, wie sich der Maus-Cursor ändert, wenn sie darüber fahren. Kann man diesen Splitter irgendwie sichtbar machen? Entweder in Form einer speziellen Linie, oder kleinen Zieh-Buttons (wie z.B. bei SolidWorks am Feature-Manager)? Hat hier jemand eine Idee? ------------------ Klaus http://www.alko-tech.com | mein Gästebuch [Diese Nachricht wurde von KMassler am 30. Aug. 2017 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
HenryV Mitglied Konstrukteur, Engineering
Beiträge: 778 Registriert: 18.05.2005 SolidWorks 2020 x64 SP3.0 Dell Precision 5820 Intel Xeon W-2125 4x4GHz NVIDIA Quadro P2000 5GB 32GB RAM 2x Dell U2412M, 24" TFT Windows 10 Enterprise x64 21H1 Microsoft Office 365 ProPlus Microsoft Visual Studio Enterprise 2022
|
erstellt am: 31. Aug. 2017 10:44 <-- editieren / zitieren --> Unities abgeben: Nur für KMassler
Hallo Klaus Ich sehe da 4 Möglichkeiten 1. Borderstyle des SplitContainer auf Fixed3D umstellen 2. BackColor des SplitContainer z.B. auf Schwarz stellen und die Panel zurück auf die Farbe "Control" setzen 3. Ein BackgroungImage im SplitContainer verwenden 4. Ein Customcontrol verwenden z.B. Collapsible Split Container
Gruss Andreas ------------------ 21 ist nur die halbe Antwort. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KMassler Ehrenmitglied V.I.P. h.c. CAD Admin + Mädchen für Alles...
Beiträge: 2657 Registriert: 06.11.2000
|
erstellt am: 31. Aug. 2017 14:58 <-- editieren / zitieren --> Unities abgeben:
Hallo Andreas, danke für die Tipps. Das CollapsibleSplitContainer-Control bringe ich bei mir nicht zum Laufen, das Demoprojekt bringt mir nur Fehler. Aber Punkt 2 in Verbindung mit selbst gezeichneten "Ziehpfeilen" im Paint-Ereignis sieht fast gut aus. "Fast", weil's noch nicht so richtig funktioniert: Ich habe in meinen Paint-Ereignissen Ziehpfeile reingezeichnet. Dazu die Padding-Werte der Panels so gesetzt, dass unten bzw. oben Platz für diese Pfeile frei gehalten wird. Das funktioniert super- solange die Form ansonsten leer ist:
Nun habe ich in diesen Panels andere Objekte, z.B. einfache Panels etc. eingefügt und mit "Dock" angeordnet- nur bei "Dock" wirkt sich das Padding aus. Und bei komplexeren Geschichten ist Dock recht hilfreich. Dummerweise wird dann aber mein Ziehpfeil im oberen Panel nicht mehr angezeigt, im unteren schon- wieso das denn? Auch größere Padding-Werte bringen da keinen Unterschied Ohne die Dock-Eigenschaft werden die Pfeile gemalt, dann ist der Formaufbau aber mühsam.
Was mache ich falsch bzw. was kann ich hier tun? Code: Public Class Form1 Private Sub SplitContainer1_Panel1_Paint(sender As Object, e As PaintEventArgs) Handles SplitContainer1.Panel1.Paint 'Ziehpfeile an Unterseite Dim pen As New Pen(Color.DarkBlue, 2) Dim ShadowPen As New Pen(Color.DarkGray, 2) Dim WorkPen As Pen Const MyLength = 20 Const ArrowWidth = 8 Const ArrowHeight = 8 Const MyDistance = 2 Dim X1 As Integer, X2 As Integer, Y As Integer Dim rec As Rectangle = e.ClipRectangle X1 = (rec.Width - MyLength) \ 2 X2 = X1 + MyLength Y = rec.Height - MyDistance Debug.Print("Rectangle W= " & rec.Width & " / H =" & rec.Height) WorkPen = pen With e.Graphics For c As Integer = 0 To 1 If c = 1 Then WorkPen = pen Else WorkPen = ShadowPen 'Grundlinie e.Graphics.DrawLine(WorkPen, X1 - 2 * c, Y - 2 * c, X2 - 2 * c, Y - 2 * c) 'Pfeillinie1 e.Graphics.DrawLine(WorkPen, X1 - 2 * c, Y - 2 * c, X1 - 2 * c, Y - ArrowHeight - 2 * c) 'Pfeillinie2 e.Graphics.DrawLine(WorkPen, X2 - 2 * c, Y - 2 * c, X2 - 2 * c, Y - ArrowHeight - 2 * c) 'Pfeilspitze1 e.Graphics.DrawLine(WorkPen, X1 - 2 * c, Y - ArrowHeight - 2 * c, X1 - ArrowWidth \ 2 - 2 * c, Y - ArrowHeight \ 2 - 2 * c) e.Graphics.DrawLine(WorkPen, X1 - 2 * c, Y - ArrowHeight - 2 * c, X1 + ArrowWidth \ 2 - 2 * c, Y - ArrowHeight \ 2 - 2 * c) 'Pfeilspitze2 e.Graphics.DrawLine(WorkPen, X2 - 2 * c, Y - ArrowHeight - 2 * c, X2 - ArrowWidth \ 2 - 2 * c, Y - ArrowHeight \ 2 - 2 * c) e.Graphics.DrawLine(WorkPen, X2 - 2 * c, Y - ArrowHeight - 2 * c, X2 + ArrowWidth \ 2 - 2 * c, Y - ArrowHeight \ 2 - 2 * c) Next End With End Sub Private Sub SplitContainer1_Panel2_Paint(sender As Object, e As PaintEventArgs) Handles SplitContainer1.Panel2.Paint 'Ziehpfeile an Oberseite Dim pen As New Pen(Color.DarkBlue, 2) Dim ShadowPen As New Pen(Color.DarkGray, 2) Dim WorkPen As Pen Const MyLength = 20 Const ArrowWidth = 8 Const ArrowHeight = 8 Const MyDistance = 5 Dim X1 As Integer, X2 As Integer, Y As Integer Dim rec As Rectangle = e.ClipRectangle X1 = (rec.Width - MyLength) \ 2 X2 = X1 + MyLength Y = MyDistance Debug.Print("Rectangle W= " & rec.Width & " / H =" & rec.Height) WorkPen = pen With e.Graphics For c As Integer = 0 To 1 If c = 1 Then WorkPen = pen Else WorkPen = ShadowPen 'Grundlinie e.Graphics.DrawLine(WorkPen, X1 - 2 * c, Y - 2 * c, X2 - 2 * c, Y - 2 * c) 'Pfeillinie1 e.Graphics.DrawLine(WorkPen, X1 - 2 * c, Y - 2 * c, X1 - 2 * c, Y + ArrowHeight - 2 * c) 'Pfeillinie2 e.Graphics.DrawLine(WorkPen, X2 - 2 * c, Y - 2 * c, X2 - 2 * c, Y + ArrowHeight - 2 * c) 'Pfeilspitze1 e.Graphics.DrawLine(WorkPen, X1 - 2 * c, Y + ArrowHeight - 2 * c, X1 - ArrowWidth \ 2 - 2 * c, Y + ArrowHeight \ 2 - 2 * c) e.Graphics.DrawLine(WorkPen, X1 - 2 * c, Y + ArrowHeight - 2 * c, X1 + ArrowWidth \ 2 - 2 * c, Y + ArrowHeight \ 2 - 2 * c) 'Pfeilspitze2 e.Graphics.DrawLine(WorkPen, X2 - 2 * c, Y + ArrowHeight - 2 * c, X2 - ArrowWidth \ 2 - 2 * c, Y + ArrowHeight \ 2 - 2 * c) e.Graphics.DrawLine(WorkPen, X2 - 2 * c, Y + ArrowHeight - 2 * c, X2 + ArrowWidth \ 2 - 2 * c, Y + ArrowHeight \ 2 - 2 * c) Next End With End Sub End Class
Hmmm... vieleicht darf ich nicht die Paint-Methoden der Panels nehmen, sondern muss direkt in der Paint-Methode des Containers rum pfuschen? Wird nur leider etwas komplizierter ... ------------------ Klaus http://www.alko-tech.com | mein Gästebuch Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KMassler Ehrenmitglied V.I.P. h.c. CAD Admin + Mädchen für Alles...
Beiträge: 2657 Registriert: 06.11.2000 SolidWorks Start 1999 ** CSWP 01/2008 ** Dell Precision 7540 mobile Workstation, 64GB, Quadro RTX 3000; SWX2020 SP5; SAP/PLM+ECTR; DriveWorks Pro; Programmierung: VBA, aktuell Visual Studio 2017/VB.Net
|
erstellt am: 31. Aug. 2017 17:28 <-- editieren / zitieren --> Unities abgeben:
Ok, ich antworte mir schon wieder selbst Ist doch nicht so kompliziert:
Code: Private Sub SplitContainer1_Paint(sender As Object, e As PaintEventArgs) Handles SplitContainer1.Paint Dim Linepen As New Pen(Color.DarkSlateGray, 2) Dim ShadowPen As New Pen(Color.LightGray, 2) Dim WorkPen As Pen = Linepen Const Diameter = 8 Const myDistance = 10 Dim ArrowHeight As Integer = sender.splitterwidth \ 2 - 3 Dim Y As Integer = sender.splitterdistance + sender.splitterwidth \ 2 + 1 Dim rec As Rectangle = e.ClipRectangle Debug.Print("Rectangle W= " & rec.Width & " / H =" & rec.Height) With e.Graphics For c As Integer = 0 To 1 If c = 1 Then WorkPen = Linepen Else WorkPen = ShadowPen 'Grundlinie .DrawLine(WorkPen, (myDistance) - 2 * c, Y - 2 * c, (rec.Width \ 2 - myDistance) - 2 * c, Y - 2 * c) .DrawLine(WorkPen, (rec.Width \ 2 + myDistance) - 2 * c, Y - 2 * c, (rec.Width - myDistance) - 2 * c, Y - 2 * c) 'Kreis .DrawEllipse(WorkPen, (rec.Width - Diameter) \ 2 - 2 * c, Y - Diameter \ 2 - 2 * c, Diameter, Diameter) Next End With Linepen.Dispose() WorkPen.Dispose() ShadowPen.Dispose() End Sub
ergibt dieses Bild: Da ist der Phantasie keine Grenzen gesetzt. Beim Ziehen funktioniert das wunderbar. Aber: Beim Verändern der Form-Größe oder wenn die Form mal in den Hintergrund gerät etc., dann wird dieses Bildchen nicht mehr oder nicht mehr komplett dargestellt. Warum? Wird da Paint von dem Container nicht aufgerufen? ------------------ Klaus
http://www.alko-tech.com | mein Gästebuch [Diese Nachricht wurde von KMassler am 01. Sep. 2017 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
HenryV Mitglied Konstrukteur, Engineering
Beiträge: 778 Registriert: 18.05.2005 SolidWorks 2020 x64 SP3.0 Dell Precision 5820 Intel Xeon W-2125 4x4GHz NVIDIA Quadro P2000 5GB 32GB RAM 2x Dell U2412M, 24" TFT Windows 10 Enterprise x64 21H1 Microsoft Office 365 ProPlus Microsoft Visual Studio Enterprise 2022
|
erstellt am: 31. Aug. 2017 17:48 <-- editieren / zitieren --> Unities abgeben: Nur für KMassler
Hallo Klaus Vielleicht noch Code: Private Sub SplitContainer1_SizeChanged(sender As Object, e As System.EventArgs) Handles SplitContainer1.SizeChanged SplitContainer1.Refresh() End Sub
Gruss Andreas ------------------ 21 ist nur die halbe Antwort. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KMassler Ehrenmitglied V.I.P. h.c. CAD Admin + Mädchen für Alles...
Beiträge: 2657 Registriert: 06.11.2000
|
erstellt am: 01. Sep. 2017 12:28 <-- editieren / zitieren --> Unities abgeben:
Vielen Dank das macht das Ganze schon viel schöner. Nächstes Problem: Ich möchte die Größe der Panele mit einfachem Mausklick anpassen- wenn ich oberhalb der Ziehlinie klicke, soll das obere Panel auf Minimum switchen, beim Klick unterhalb der Ziehlinie das untere Panel. Dazu wird der Wert von SplitterDistance entsprechend angepasst. Zum Abfangen der Mausklicks verwende ich MouseDown und MouseUp. Bei MouseDown wird die Mausposition gespeichert, bei MouseUp die gespeicherte mit der aktuellen verglichen. Wenn die gleich sind und im definierten Bereich oberhalb oder unterhalb der Ziehlinie, soll die Aktion erfolgen. Komischerweise passiert das aber erst bei einem Doppelklick. Man sieht beim einfachen Klick, dass der Splitter kurz an die neue Position springt, anschließend kommt er aber wieder zurück. Erst beim Doppleklick bleibt er dort wo er hin soll.
Code: Dim SplitterClickPos As New Point(0, 0) Private Sub SplitContainer1_MouseDown(sender As Object, e As MouseEventArgs) Handles SplitContainer1.MouseDown SplitterClickPos.X = e.X SplitterClickPos.Y = e.Y End Sub Private Sub SplitContainer1_MouseUp(sender As Object, e As MouseEventArgs) Handles SplitContainer1.MouseUp Dim MidY As Integer = SplitContainer1.SplitterDistance + SplitContainer1.SplitterWidth \ 2 If SplitterClickPos.X <> e.X Or SplitterClickPos.Y <> e.Y Then Exit Sub ' Nix machen, wenn Mouse verschoben wurde If e.Y < MidY - 1 Then SplitContainer1.SplitterDistance = SplitContainer1.Panel1MinSize ElseIf e.Y > MidY + 1 Then SplitContainer1.SplitterDistance = SplitContainer1.Height - SplitContainer1.SplitterWidth - SplitContainer1.Panel2MinSize End If End Sub
Noch seltsamer: Beim Klick mit der rechten Maustaste funktioniert's mit einfachem Klick! ------------------ Klaus http://www.alko-tech.com | mein Gästebuch Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
HenryV Mitglied Konstrukteur, Engineering
Beiträge: 778 Registriert: 18.05.2005 SolidWorks 2020 x64 SP3.0 Dell Precision 5820 Intel Xeon W-2125 4x4GHz NVIDIA Quadro P2000 5GB 32GB RAM 2x Dell U2412M, 24" TFT Windows 10 Enterprise x64 21H1 Microsoft Office 365 ProPlus Microsoft Visual Studio Enterprise 2022
|
erstellt am: 04. Sep. 2017 11:57 <-- editieren / zitieren --> Unities abgeben: Nur für KMassler
Hallo Klaus Hab ein bisschen experimentiert. Komischerweise wird die SplitterDistance nach dem MouseUp resettet. Mit nachfolgendem Code funktioniert es auch mit einem Klick. Code: Private Sub SplitContainer1_Layout(sender As Object, e As System.Windows.Forms.LayoutEventArgs) Handles SplitContainer1.Layout If iSplitterDistance <> 0 And Mouse_Down = False Then SplitContainer1.SplitterDistance = iSplitterDistance End SubPrivate Sub SplitContainer1_Paint(sender As Object, e As PaintEventArgs) Handles SplitContainer1.Paint Dim Linepen As New Pen(Color.DarkSlateGray, 2) Dim ShadowPen As New Pen(Color.LightGray, 2) Dim WorkPen As Pen = Linepen Dim s As SplitContainer = CType(sender, SplitContainer) s.SplitterWidth = 50 Const Diameter As Integer = 8 Const myDistance As Integer = 10 Dim ArrowHeight As Integer = s.SplitterWidth \ 2 - 3 Dim Y As Integer = s.SplitterDistance + s.SplitterWidth \ 2 + 1 Dim rec As Rectangle = e.ClipRectangle 'Debug.Print("Rectangle W= " & rec.Width & " / H =" & rec.Height) With e.Graphics For c As Integer = 0 To 1 If c = 1 Then WorkPen = Linepen Else WorkPen = ShadowPen 'Grundlinie .DrawLine(WorkPen, (myDistance) - 2 * c, Y - 2 * c, (rec.Width \ 2 - myDistance) - 2 * c, Y - 2 * c) .DrawLine(WorkPen, (rec.Width \ 2 + myDistance) - 2 * c, Y - 2 * c, (rec.Width - myDistance) - 2 * c, Y - 2 * c) 'Kreis .DrawEllipse(WorkPen, (rec.Width - Diameter) \ 2 - 2 * c, Y - Diameter \ 2 - 2 * c, Diameter, Diameter) Next End With Linepen.Dispose() WorkPen.Dispose() ShadowPen.Dispose() End Sub Private Sub SplitContainer1_SizeChanged(sender As Object, e As System.EventArgs) Handles SplitContainer1.SizeChanged SplitContainer1.Refresh() End Sub Private Sub SplitContainer1_MouseDown(sender As Object, e As MouseEventArgs) Handles SplitContainer1.MouseDown SplitterClickPos.X = e.X SplitterClickPos.Y = e.Y Mouse_Down = True End Sub Private Sub SplitContainer1_MouseUp(sender As Object, e As MouseEventArgs) Handles SplitContainer1.MouseUp If SplitterClickPos.X = e.X Or SplitterClickPos.Y = e.Y Then ' Nix machen, wenn Mouse verschoben wurde Dim MidY As Integer = SplitContainer1.SplitterDistance + SplitContainer1.SplitterWidth \ 2 If e.Y < MidY - 1 Then SplitContainer1.SplitterDistance = SplitContainer1.Panel1MinSize ElseIf e.Y > MidY + 1 Then SplitContainer1.SplitterDistance = SplitContainer1.Height - SplitContainer1.SplitterWidth - SplitContainer1.Panel2MinSize End If iSplitterDistance = SplitContainer1.SplitterDistance End If Mouse_Down = False End Sub Private Sub SplitContainer1_SplitterMoved(sender As Object, e As System.Windows.Forms.SplitterEventArgs) Handles SplitContainer1.SplitterMoved SplitContainer1.Refresh() End Sub Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load Me.DoubleBuffered = True End Sub
Leider gibt es bei mir zwischendurch Grafikfehler. Mit folgendem Code kann man durch aktivieren eines anderen Controls zumindest ein neu zeichnen auslösen.
Code: Private Sub SplitContainer1_LostFocus(sender As Object, e As System.EventArgs) Handles SplitContainer1.LostFocus SplitContainer1.Refresh() End Sub
Mir ist zusätzlich aufgefallen, dass durch das auswählen des SplitContainers mit der Tabulatortaste die Striche verschwinden. Ich habe dies durch SplitContainer1.TabStop = False verhindert. Gruss Andreas ------------------ 21 ist nur die halbe Antwort. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KMassler Ehrenmitglied V.I.P. h.c. CAD Admin + Mädchen für Alles...
Beiträge: 2657 Registriert: 06.11.2000
|
erstellt am: 05. Sep. 2017 14:28 <-- editieren / zitieren --> Unities abgeben:
Ja, das ist doch noch einiges besser, auch wenn immer noch Darstellungsfehler auftreten. Der SplitContainer scheint so seine Probleme zu haben. Aber noch eine Verständnisfrage an den Fachmann : Sind die dispose-Anweisungen für Font, Pen, Brush etc. eigentlich erforderlich? Normalerweise sollte das doch wohl automatisch passieren? Das habe ich aus irgendeinem Beispiel heraus übernommen, bin bisher aber immer ohne diese expliziten Aufräum-Anweisungen ausgekommen. Gerade wollte ich auch noch nachhaken, warum du den SplitContainer nochmal deklarierst mit Dim s As SplitContainer = CType(sender, SplitContainer) aber das habe ich jetzt begriffen. [Edit] Gerade in einem anderen Programm, wo ich den SplitContainer bisher unverändert verwendet habe: Wenn ich hier die SplitterWidth ändere, z.B. auf 20 oder 50 oder ..., dann habe ich hier den Effekt, dass dieser Splitter nach dem Programmstart in der ursprünglichen Standardbreite (4) dargestellt wird. Da hilft auch kein Rütteln und Schütteln. Wenn ich nun in der Paint-Methode die Zeilen
Code: Dim s As SplitContainer = CType(sender, SplitContainer) s.SplitterWidth = 20
rein nehme, dann ist die Darstellung nach Programmstart immer noch falsch, erst wenn ich das Fenster bewege oder die Größe ändere, also das Paint durchlaufen wird, dann wird der Splitter in der definierten Breite dargestellt. Dieser Wert für SplitterWidth wird definitiv nirgendwo sonst im Programm verändert. Sehr seltsam... [/Edit] ------------------ Klaus http://www.alko-tech.com | mein Gästebuch [Diese Nachricht wurde von KMassler am 05. Sep. 2017 editiert.] [Diese Nachricht wurde von KMassler am 05. Sep. 2017 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
HenryV Mitglied Konstrukteur, Engineering
Beiträge: 778 Registriert: 18.05.2005 SolidWorks 2020 x64 SP3.0 Dell Precision 5820 Intel Xeon W-2125 4x4GHz NVIDIA Quadro P2000 5GB 32GB RAM 2x Dell U2412M, 24" TFT Windows 10 Enterprise x64 21H1 Microsoft Office 365 ProPlus Microsoft Visual Studio Enterprise 2022
|
erstellt am: 07. Sep. 2017 17:26 <-- editieren / zitieren --> Unities abgeben: Nur für KMassler
|
KMassler Ehrenmitglied V.I.P. h.c. CAD Admin + Mädchen für Alles...
Beiträge: 2657 Registriert: 06.11.2000
|
erstellt am: 08. Sep. 2017 08:24 <-- editieren / zitieren --> Unities abgeben:
In dem ursprünglichen Projekt, das mich zu diesem Thread veranlasst hat, sowie in diversen Testprojekten habe ich auch kein Problem mit dem SplitterWidth- da funktioniert alles wie hier besprochen. Nur in diesem einen älteren Projekt wird die SplitterWidth-Angabe einfach ignoriert. Da habe ich das komplette Projekt abgesucht, SplitterWidth wird definitiv nirgendwo im Code verändert. Hmm.... ------------------ Klaus http://www.alko-tech.com | mein Gästebuch Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
fritsrol Mitglied CAD-Systemingenieur
Beiträge: 143 Registriert: 11.12.2002 Windows 10 64 Office 2013 Eplan P8 2.7 HF2 VS 2015 Medusa 2000i2
|
erstellt am: 08. Sep. 2017 09:09 <-- editieren / zitieren --> Unities abgeben: Nur für KMassler
|
KMassler Ehrenmitglied V.I.P. h.c. CAD Admin + Mädchen für Alles...
Beiträge: 2657 Registriert: 06.11.2000
|
erstellt am: 08. Sep. 2017 13:22 <-- editieren / zitieren --> Unities abgeben:
|
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|