2008-11-20 6 views
5

Ich möchte in der Lage sein, ein schwarzes benutzerdefiniertes Fenster (mit Rahmen und Steuerelementen) zu erstellen, das als Teil von Expression Blend, Twirl oder Adobe Lightroom geliefert wird.Winforms - Wie erstelle ich einen benutzerdefinierten Windows-Rahmen und schließen/minimieren Schaltflächen?

Gibt es eine Best Practices-Methode zum Erstellen eines vom Besitzer gezeichneten Fensters?

Plattform: C# und Windows (alle Versionen)

+0

Hier ist der Artikel zum Erstellen benutzerdefinierter Windows-Formulare mit nur Panels - [Erstellen von benutzerdefinierten Windows Forms in C# mit Panels] (http://www.codeproject.com/Articles/1068043/Creating-Custom-Windows-Forms-in- -Charp-using-Pane) –

+0

Mögliches Duplikat von [Benutzerdefinierte Titelleisten/Chrome in einer WinForms App] (http://StackOverflow.com/questions/42460/custom-titlebars-chrome-in-a-winforms-app) –

Antwort

4

Wenn die benutzerdefinierten-Chrom-Tools Sie nicht mit dem bieten Look-and-Feel, die Sie wollen, diese Art der Sache ist einfach sich in C# zu tun. Grundsätzlich erstellen Sie eine randlose Form (FormBorderStyle = None) und erstellen dann alle Steuerelemente und Rahmen selbst, indem Sie die Steuerelemente dort platzieren, wo Sie sie brauchen (eine Beschriftung für die Titelleiste, Befehlsschaltflächen zum Schließen und Minimieren etc.) und/oder Zeichnen direkt auf der Oberfläche des Formulars mit dem Graphics-Objekt.

Sie müssen auch Code implementieren, um das Formular durch seine "falsche" Titelleiste ziehen zu lassen (siehe this answer für ein Beispiel, wie dies zu tun ist). Möglicherweise müssen Sie auch Ihren eigenen Größenänderungsmechanismus implementieren (wenn die Größe der Formulare geändert werden muss).

Schließlich, obwohl der benutzerdefinierte Form Code ein wenig klobig sein kann, können Sie es in einem einzigen Formular implementieren und dann alle anderen Formulare in Ihrer Anwendung von diesem Formular erben, was es zu einer sehr nützlichen Technik für benutzerdefinierte macht -Haut eine ganze Anwendung.

+0

Ehrlich ein sehr fairer Ansatz –

2

Meine Aufgabe war es, aktive Fenster auffälliger, heller zu machen - als andere, inaktive Fenster der App. App hat viele geöffnete Fenster, einige modale, einige nicht modale - und das MDI Elternteil.

Sie können etwas wie not-a-border verwenden - einen Rahmen im Client-Bereich. Hier ist der Code-Schnipsel, ein Teil einer Basisklasse (direkt in einer Form verwendet werden kann):

#region Кастомизированное поведение - рамки, активность и т.д. 
    private bool isCurrentlyActive = false; 
    private bool childControlsAreHandled = false; 
    private Pen activeWindowFramePen, inactiveWindowFramePen; 
    private Point[] framePoints; 

    private void AddControlPaintHandler(Control ctrl) 
    { 
     ctrl.Paint += DrawWindowFrame; 
     if (ctrl.Controls != null) 
     { 
      foreach (Control childControl in ctrl.Controls) 
      { 
       AddControlPaintHandler(childControl); 
      } 
     } 
    } 

    protected override void OnActivated(EventArgs e) 
    { 
     base.OnActivated(e); 
     if ((this.childControlsAreHandled == false) 
      && (WindowFrameType != Forms.WindowFrameType.NoFrame) 
      && (this.MdiParent == null)) 
     { 
      RecalculateWindowFramePoints(); 
      AddControlPaintHandler(this); 
      this.childControlsAreHandled = true; 
     } 

     this.isCurrentlyActive = true; 
     if (InactiveWindowOpacity < 1) 
     { 
      base.Opacity = 1; 
     } 
     base.Invalidate(true); 
    } 

    protected override void OnDeactivate(EventArgs e) 
    { 
     base.OnDeactivate(e); 
     this.isCurrentlyActive = false; 
     if (InactiveWindowOpacity < 1) 
     { 
      base.Opacity = InactiveWindowOpacity; 
     } 
     base.Invalidate(true); 
    } 

    protected override void OnResizeEnd(EventArgs e) 
    { 
     base.OnResizeEnd(e); 
     this.framePoints = null; 
     RecalculateWindowFramePoints(); 
     this.Invalidate(true); 
    } 

    private Pen ActivePen 
    { 
     get 
     { 
      if (this.isCurrentlyActive) 
      { 
       if (this.activeWindowFramePen == null) 
       { 
        this.activeWindowFramePen = new Pen(Color.FromArgb((int)(WindowFrameOpacity*255), WindowFrameActiveColor), WindowFrameSize * 2); 
       } 
       return this.activeWindowFramePen; 
      } 
      else 
      { 
       if (this.inactiveWindowFramePen == null) 
       { 
        this.inactiveWindowFramePen = new Pen(Color.FromArgb((int)(WindowFrameOpacity*255), WindowFrameInactiveColor), WindowFrameSize * 2); 
       } 
       return this.inactiveWindowFramePen; 
      } 
     } 
    } 

    private Point[] RecalculateWindowFramePoints() 
    { 
     if ((WindowFrameType == Forms.WindowFrameType.AllSides) 
      && (this.framePoints != null) 
      && (this.framePoints.Length != 5)) 
     { 
      this.framePoints = null; 
     } 
     if ((WindowFrameType == Forms.WindowFrameType.LeftLine) 
      && (this.framePoints != null) 
      && (this.framePoints.Length != 2)) 
     { 
      this.framePoints = null; 
     } 
     if (this.framePoints == null) 
     { 
      switch (WindowFrameType) 
      { 
       case Forms.WindowFrameType.AllSides: 
        this.framePoints = new Point[5] 
        { 
         new Point(this.ClientRectangle.X, this.ClientRectangle.Y), 
         new Point(this.ClientRectangle.X + this.ClientRectangle.Width, this.ClientRectangle.Y), 
         new Point(this.ClientRectangle.X + this.ClientRectangle.Width, this.ClientRectangle.Y + this.ClientRectangle.Height), 
         new Point(this.ClientRectangle.X, this.ClientRectangle.Y + this.ClientRectangle.Height), 
         new Point(this.ClientRectangle.X, this.ClientRectangle.Y) 
        }; 
        break; 
       case Forms.WindowFrameType.LeftLine: 
        this.framePoints = new Point[2] 
        { 
         new Point(this.ClientRectangle.X, this.ClientRectangle.Y), 
         new Point(this.ClientRectangle.X, this.ClientRectangle.Y + this.ClientRectangle.Height) 
        }; 
        break; 
      } 
     } 
     return this.framePoints; 
    } 

    private void DrawWindowFrame(object sender, PaintEventArgs e) 
    { 
     if (WindowFrameType == Forms.WindowFrameType.NoFrame) 
     { 
      return; 
     } 
     if ((this.framePoints == null) || (this.framePoints.Length == 0)) 
     { 
      return; 
     } 
     Control ctrl = (Control)(sender); 
     // пересчитаем точки в координатах контрола. 
     List<Point> pts = new List<Point>(); 
     foreach (var p in this.framePoints) 
     { 
      pts.Add(ctrl.PointToClient(this.PointToScreen(p))); 
     } 
     e.Graphics.DrawLines(ActivePen, pts.ToArray()); 
    } 

    public static int WindowFrameSize = 2; 
    public static WindowFrameType WindowFrameType = Forms.WindowFrameType.NoFrame; 
    public static Color WindowFrameActiveColor = Color.YellowGreen; 
    public static Color WindowFrameInactiveColor = SystemColors.ControlDark; 
    public static double InactiveWindowOpacity = 1.0; 
    public static double WindowFrameOpacity = 0.3; 
    #endregion 

Statische Felder der Klasse initialisiert wird von Anwendungseinstellungen Form (Klasse) - so, alle Formen in Die App hat das gleiche Verhalten.

Hoffe, dass jemand hilft.

+0

wo finde ich diesen Typ WindowFrameType ?? – user1912383

Verwandte Themen