Benutzer mit den meisten Antworten
Form mit Rand? (BorderStyle = None)

Frage
Antworten
-
Na sowas. Dann würde ich dich bitten, deine Testanwendung auf SkyDrive oder vergleichbares hochzuladen, damit ich mir sie mal ansehe und herausfinde, warum sie nicht so aussieht:
;-)
P.S. Das Uploaden ist nicht mehr notwendig. Du hast - warum auch immer - die BackgroundColor-Eigenschaft deiner Controls auf Transparent gesetzt. Ändere das mal auf SystemColors.Control und gut ist. Tipp: Damit Du dir nicht in die Quere kommst mit dem Zeichnen der anderen Controls, kannst Du im Konstruktor deiner Form noch folgendes hinzufügen:
public SolidBorderForm() { InitializeComponent(); Padding = new Padding(WIDTH); }
- Bearbeitet Marcel RomaModerator Dienstag, 22. Januar 2013 13:21 P.S.
- Als Antwort markiert XxDeadLiiNexX Dienstag, 22. Januar 2013 14:36
- Tag als Antwort aufgehoben XxDeadLiiNexX Dienstag, 22. Januar 2013 14:36
- Als Antwort markiert XxDeadLiiNexX Dienstag, 22. Januar 2013 14:44
-
Gerne. Schön, dass es auch bei dir geklappt hat.
Meine ersten Schritte in Sachen Programmierung stammen aus den späten Jahren des Triumph Adler Alphatronic PCs, als die PCs noch keine Festplatten hatten, Betriebsysteme vom Floppy geladen wurden und Monitore mit orangener Schrift als fortschrittlich galten. Diese Erfahrung ist nicht immer ein Vorteil. Sie hat aber mir und meinen Kunden so manches mal aus der Patsche geholfen.
Bis zum nächsten Mal.
- Als Antwort markiert XxDeadLiiNexX Dienstag, 22. Januar 2013 15:34
Alle Antworten
-
Guten Morgen XxDeadLiiNexX,
Ja, Du könntest z.B. den Rand selber zeichnen:
using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class SolidBorderForm : Form { public SolidBorderForm() { InitializeComponent(); FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; } private const int WIDTH = 3; Color COLOR = Color.BlueViolet; protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle, // Rahmen-Rechteck COLOR, WIDTH, ButtonBorderStyle.Solid, // Rahmen-Farbe, -Breite und -Art: LINKS COLOR, WIDTH, ButtonBorderStyle.Solid, // Rahmen-Farbe, -Breite und -Art: OBEN COLOR, WIDTH, ButtonBorderStyle.Solid, // Rahmen-Farbe, -Breite und -Art: RECHTS COLOR, WIDTH, ButtonBorderStyle.Solid); // Rahmen-Farbe, -Breite und -Art: UNTEN } } }
Das könnte dann z.B. so aussehen:
Gruß
Marcel
- Bearbeitet Marcel RomaModerator Dienstag, 22. Januar 2013 09:40 Bild aktualisiert
-
Aber jetzt ist alles umrandet [...] Wie kann ich ihm sagen das er nur die Form umranden soll?
Wenn Du mit "alles" das Hauptfenster deiner Applikation meinst, dann hast Du den Code in die falschen Klasse eingefügt. Öffne den Code-Editor deiner rahmenlosen Form und füge den Code dort ein. -
Erstmal danke für die Antwort und den neuen Code !
Das gibts nicht :-S
Wenn ich ne neue Windows Forms Anwendung mache ein paar Buttons hineinziehe und deinen Code reinpacke funktioniert es! Ist übrigens genau das was ich brauche :-P
Aber bei meiner jetzigen Anwendung funktioniert es nicht, er umrandet alle Steuerelement mhm...
-
Wenn ich ne neue Windows Forms Anwendung mache ein paar Buttons hineinziehe und deinen Code reinpacke funktioniert es! Ist übrigens genau das was ich brauche
Wunderbar.
Aber bei meiner jetzigen Anwendung funktioniert es nicht, er umrandet alle Steuerelemente
Cool. Deinen Code, der imstande ist, über ControlPaint.DrawBorder(e.Graphics, ...) auf die GDI+-Zeichnungsoberfläche anderer Controls zu zeichnen, möchte ich unbedingt sehen. Und ich meine deinen Code, nicht meinen.
- Bearbeitet Marcel RomaModerator Dienstag, 22. Januar 2013 10:13
-
Na sowas. Dann würde ich dich bitten, deine Testanwendung auf SkyDrive oder vergleichbares hochzuladen, damit ich mir sie mal ansehe und herausfinde, warum sie nicht so aussieht:
;-)
P.S. Das Uploaden ist nicht mehr notwendig. Du hast - warum auch immer - die BackgroundColor-Eigenschaft deiner Controls auf Transparent gesetzt. Ändere das mal auf SystemColors.Control und gut ist. Tipp: Damit Du dir nicht in die Quere kommst mit dem Zeichnen der anderen Controls, kannst Du im Konstruktor deiner Form noch folgendes hinzufügen:
public SolidBorderForm() { InitializeComponent(); Padding = new Padding(WIDTH); }
- Bearbeitet Marcel RomaModerator Dienstag, 22. Januar 2013 13:21 P.S.
- Als Antwort markiert XxDeadLiiNexX Dienstag, 22. Januar 2013 14:36
- Tag als Antwort aufgehoben XxDeadLiiNexX Dienstag, 22. Januar 2013 14:36
- Als Antwort markiert XxDeadLiiNexX Dienstag, 22. Januar 2013 14:44
-
Gerne. Schön, dass es auch bei dir geklappt hat.
Meine ersten Schritte in Sachen Programmierung stammen aus den späten Jahren des Triumph Adler Alphatronic PCs, als die PCs noch keine Festplatten hatten, Betriebsysteme vom Floppy geladen wurden und Monitore mit orangener Schrift als fortschrittlich galten. Diese Erfahrung ist nicht immer ein Vorteil. Sie hat aber mir und meinen Kunden so manches mal aus der Patsche geholfen.
Bis zum nächsten Mal.
- Als Antwort markiert XxDeadLiiNexX Dienstag, 22. Januar 2013 15:34
-
Na sowas. Dann würde ich dich bitten, deine Testanwendung auf SkyDrive oder vergleichbares hochzuladen, damit ich mir sie mal ansehe und herausfinde, warum sie nicht so aussieht:
;-)
P.S. Das Uploaden ist nicht mehr notwendig. Du hast - warum auch immer - die BackgroundColor-Eigenschaft deiner Controls auf Transparent gesetzt. Ändere das mal auf SystemColors.Control und gut ist. Tipp: Damit Du dir nicht in die Quere kommst mit dem Zeichnen der anderen Controls, kannst Du im Konstruktor deiner Form noch folgendes hinzufügen:
public SolidBorderForm() { InitializeComponent(); Padding = new Padding(WIDTH); }
Moin Marcel Roma!
ich würde nochmal deine Hilfe benötigen, und zwar hab ich mit dieser Zeichen Methode folgendes Problem:
Wenn das Programm startet und ich es anschließend nehmen und beim Monitor Rand hinaus schiebe und anschließend wieder rein ziehe sind alles Striche vom sozusagen Monitor Rand in der Form.
Kann man dagegen was machen?
Mit freundlichen Grüßen!
P.S das ist ein anders Konto alos nicht wundern gg*
-
Moin moin.
mit welcher Zeichenmethode hat Du denn Probleme? Könntest Du eine Bildschirmkopie posten? Ist das Problem auch mit anderen Grafikkarten, auf anderen Systemen replizierbar?
Gruß
MarcelMoin!
Freut mich erstmal das du antwortet, ja das Problem ist replizierbar, denke das es am Code liegt und man die Form sozusagen schützen muss. Verwenden tu ich denn Code denn du oben/damals gepostet hast.
Ich schick poste jetzt einfach 2 Screenshots dazu dann weisst du bestimmt was ich mein :-)
Beim ersten Bild befindet sich das Programm ganz normal am Desktop, dann zieh ich es mit der Maus über denn Bildschirm Rand hinaus, als würde ich es verstecken wollen gg*
Beim zweiten Bild zieh ich das Programm was hinter dem Bildschirm Rand steckt wieder rein, jetzt sind die ganzen Striche vom Bildschirm Rand auf der Form.
Mfg! :D
-
Hallo,
So wie's aussieht, hat deine Anwendung nicht genügend Zeit/Ressourcen zur Verfügung, die erhaltenen WM_PAINT-Nachrichten im OnPaint zu verarbeiten. Die Verarbeitung geschieht dadurch intermitent; deshalb die gestrichelten Linien auf dem Bildschirm.
Versuchst Du die Form zu animieren (z.B. aus dem Off-Screenbereich über eine Reihe von Animationsschritten wieder in den sichtbaren Bereich zu bringen)? Dann musst Du auch dafür sorgen, dass dies asynchron passiert und die Verarbeitung der Windows-Nachrichten noch möglich ist. So hat deine Anwendung genug "Luft" um richtig zu "sitzen" und zu "wackeln".Überprüfe also ob Du DoubleBuffering verwendest, ob enge Schleifen beim Bewegen des Fensters alle Ressourcen binden, ob ein Timer dabei häufig feuert etc.
Idealerweise verschiebst Du dann alle blockierenden Aktionen auf einen Nebenthread damit die UI zeitnah auf Benutzerinteraktion reagieren kann.
Gruß
Marcel -
Hallo,
anstatt e.ClipRectangle sollte man den kompletten Rahmen zeichnen, denn ClipRectangle optimiert ggf. Teile des Randes weg (weil nicht sichtbar) - was zu einem falschen Rahmen führen kann:
var bounds = new Rectangle(Point.Empty, this.Size); ControlPaint.DrawBorder(e.Graphics, bounds, // Rahmen-Rechteck COLOR, WIDTH, ButtonBorderStyle.Solid, // Rahmen-Farbe, -Breite und -Art: LINKS COLOR, WIDTH, ButtonBorderStyle.Solid, // Rahmen-Farbe, -Breite und -Art: OBEN COLOR, WIDTH, ButtonBorderStyle.Solid, // Rahmen-Farbe, -Breite und -Art: RECHTS COLOR, WIDTH, ButtonBorderStyle.Solid); // Rahmen-Farbe, -Breite und -Art: UNTEN
Gruß Elmar- Als Antwort vorgeschlagen XxDeadLiinexXx Montag, 25. November 2013 12:21
-
Hi Elmar,
ClipRectangle ist nicht das eigentliche Problem hier. Der geloggte Wert mag zwar nicht der sein, den Du erwartest, und er mag nicht zur der aktuellen Location passen. Aber er war sicherlich gültig zum Zeitpunkt als ClipRectangle für den zu zeichnenden Teilbereich gesetzt wurde.
Die Location-Änderung geschieht jedoch so schnell, dass die WM_PAINT Nachrichten zu einem Zeitpunkt eintreffen bzw. verarbeitet werden könne, wo die Werte nicht mehr aktuell sind.
Indem man in OnPaint mit der aktuellen Größe des Clients arbeitet, umgeht man das Problem zum größten Teil, da hast Du Recht. Aber es ist nicht der einzige Weg mit dem eigentlichen Problem umzugehen.Durch Setzen von this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true) kann man dafür sorgen, dass das Zeichnen "am Stück" und in OnPaint() geschieht, was für ein flüssigeres Zeichnen sorgt. Dies wird umso wichtiger, je größer die Strecke ist über die man die Form bewegt.
Durch Auslagerung des Codes zum Ändern der Location auf ein Nebenthread, wird der aktuelle Thread von Blockaden befreit und kann die WM_Nachrichten schneller bearbeiten.
Durch Setzen von GCSettings.LatencyMode = GCLatencyMode.LowLatency kann man während der Animation dafür sorgen, dass der GC nicht den Thread unterbricht.
Hier ein kurzes Konzept, damit Du besser verstehst, was ich meine:
using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Runtime; using System.Threading; using System.Windows.Forms; namespace WindowsFormsApplication1 { public class FormSlidingAnimation : IDisposable { private const int DEFAULT_FRAME_RATE = 35; private const int DEFAULT_INCREMENT = 35; private readonly SynchronizationContext _syncContext; private readonly Form _formToSlideIntoView; private AutoResetEvent _autoResetEvent; private Point _currentXLocation; private System.Threading.Timer _timer; public FormSlidingAnimation(Form formToSlideIntoView) { FramesPerSecond = DEFAULT_FRAME_RATE; LocationIncrement = DEFAULT_INCREMENT; // Für eine flüssigere Darstellung sollte man im // Konstruktor von formToSlideIntoView folgende Zeile // einfügen: // this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true) _formToSlideIntoView = formToSlideIntoView; _currentXLocation = _formToSlideIntoView.Location; _syncContext = SynchronizationContext.Current; } public void Start() { GCSettings.LatencyMode = GCLatencyMode.LowLatency; _autoResetEvent = new AutoResetEvent(false); Thread timerThread = new Thread(OnRunTimerThread); timerThread.Start(); } private void OnRunTimerThread() { var period = 1000 / FramesPerSecond; _timer = new System.Threading.Timer(OnTimerCallback, null, 0, period); } private void OnTimerCallback(object state) { if (_currentXLocation.X < (Screen.PrimaryScreen.WorkingArea.Width / 2) - (_formToSlideIntoView.Width / 2)) { _currentXLocation = new Point(_currentXLocation.X, (Screen.PrimaryScreen.WorkingArea.Height / 2) - (_formToSlideIntoView.Height / 2)); _syncContext.Post(_ => { _formToSlideIntoView.Location = _currentXLocation; _formToSlideIntoView.Invalidate(); }, _currentXLocation); _currentXLocation.X += LocationIncrement; } else { _timer.Change(Timeout.Infinite, Timeout.Infinite); _autoResetEvent.Set(); _timer.Dispose(); GCSettings.LatencyMode = GCLatencyMode.Interactive; } } public int FramesPerSecond { get; set; } public int LocationIncrement { get; set; } public void Dispose() { if (_timer != null) _timer.Dispose(); if (_formToSlideIntoView != null) _formToSlideIntoView.Dispose(); if (_autoResetEvent != null) { _autoResetEvent.Dispose(); _autoResetEvent = null; } } } }
Verwendung der Klasse aus der zu verschiebenden Form-Klasse (deren UI sich ausserhalb des Screens befindet):
FormSlidingAnimation animation = new FormSlidingAnimation(this); animation.Start();
Noch bessere Performance erzielt man, indem man nicht die Form, sondern ein Abbild der Form über den Bildschirm bewegt und erst zuguterletzt die Form hinter dem Bild einblendet.
Ich konnte keine großen Unterschiede feststellen, zwischen der Verwendung von ClipRectangle und new Rectangle(Point.Empty, this.Size). Aber vielleicht kannst Du einiges mehr dazu sagen/schreiben.
Gruß
Marcel- Bearbeitet Marcel RomaModerator Montag, 25. November 2013 11:25
- Als Antwort vorgeschlagen XxDeadLiinexXx Montag, 25. November 2013 12:24
-
Hallo Marcel,
man kann natürlich optimieren usw. - aber auch minimalistisch geht es:
using System.Drawing; using System.Windows.Forms; namespace ElmarBoye.Samples.Forms { public partial class SolidBorderForm : Form { private const int WIDTH = 3; Color COLOR = Color.BlueViolet; public SolidBorderForm() { InitializeComponent(); base.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); //base.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); base.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; base.Size = new Size(800, 600); base.Padding = new Padding(WIDTH); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); var bounds = new Rectangle(Point.Empty, this.Size); //Console.WriteLine("{0} => {1}", bounds, e.ClipRectangle); ControlPaint.DrawBorder(e.Graphics, bounds, COLOR, WIDTH, ButtonBorderStyle.Solid, COLOR, WIDTH, ButtonBorderStyle.Solid, COLOR, WIDTH, ButtonBorderStyle.Solid, COLOR, WIDTH, ButtonBorderStyle.Solid); } private bool isDragging; private Point dragLocation; protected override void OnMouseDown(MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { this.isDragging = true; this.dragLocation = new Point(e.X, e.Y); } } protected override void OnMouseUp(MouseEventArgs e) { this.isDragging = false; } protected override void OnMouseMove(MouseEventArgs e) { if (this.isDragging) { Point location = PointToScreen(e.Location); this.Location = new Point(location.X - this.dragLocation.X, location.Y - this.dragLocation.Y); } } } }
(Das Verschieben ist zum Testen nur halbseiden implementiert ;)
Gruß Elmar
-
Hallo,
anstatt e.ClipRectangle sollte man den kompletten Rahmen zeichnen, denn ClipRectangle optimiert ggf. Teile des Randes weg (weil nicht sichtbar) - was zu einem falschen Rahmen führen kann:
var bounds = new Rectangle(Point.Empty, this.Size); ControlPaint.DrawBorder(e.Graphics, bounds, // Rahmen-Rechteck COLOR, WIDTH, ButtonBorderStyle.Solid, // Rahmen-Farbe, -Breite und -Art: LINKS COLOR, WIDTH, ButtonBorderStyle.Solid, // Rahmen-Farbe, -Breite und -Art: OBEN COLOR, WIDTH, ButtonBorderStyle.Solid, // Rahmen-Farbe, -Breite und -Art: RECHTS COLOR, WIDTH, ButtonBorderStyle.Solid); // Rahmen-Farbe, -Breite und -Art: UNTEN
Gruß Elmar
Super das wars, dankschön!
Großes Danke an alle für die Mühe und den Aufwand :-)
-
Hi XxDeadLiinexXx,
gerne, vielleicht hilftst Du auch mal in diesem Forum mit. Das wäre toll.
Mir ist aufgefallen, dass Du einen neuen Kontonamen verwendest (Januar: XxDeadLiiNexX, aktuell: XxDeadLiinexXx) weswegen Du wahrscheinlich in diesem Thread keine Antworten markieren kannst.
Wenn Du möchtest, kann ich das für dich erledigen, gib einfach Bescheid. Kann ich dir mit dem alten Konto behilflich sein?
Gruß
Marcel