2008-11-20 6 views
5

Je voudrais être en mesure de créer une fenêtre personnalisée en noir (avec bordure et contrôles) comme celle fournie dans le cadre de l'expression blend, Twirl ou Adobe Lightroom.Winforms - Comment créer une bordure de fenêtre personnalisée et fermer/réduire les boutons?

Existe-t-il un moyen de créer une fenêtre dessinée par le propriétaire?

Plate-forme: C# et WindowsForms (toute version)

+0

Voici l'article pour créer des formulaires Windows personnalisés en utilisant uniquement des panneaux - [Création de formulaires Windows personnalisés en C# en utilisant des panneaux] (http://www.codeproject.com/Articles/1068043/Creating-Custom-Windows-Forms-in -Csharp-using-Pane) –

+0

Copie possible de [Barres de titre personnalisées/chrome dans une application WinForms] (http://stackoverflow.com/questions/42460/custom-titlebars-chrome-in-a-winforms-app) –

Répondre

4

Si les outils chrome personnalisés ne vous donnent pas le look and feel que vous voulez, ce genre de chose est facile se faire en C#. Fondamentalement, vous créez un formulaire sans bordure (FormBorderStyle = None) puis créez vous-même tous les contrôles et bordures, en plaçant les contrôles là où vous en avez besoin (une étiquette pour la barre de titre, les boutons de commande pour fermer et minimiser) et/ou directement sur la surface du formulaire en utilisant l'objet Graphics.

Vous devez également implémenter du code pour permettre au formulaire d'être déplacé par sa barre de titre «fausse» (voir this answer pour un exemple de procédure). Vous devrez peut-être également implémenter votre propre mécanisme de redimensionnement (si vous avez besoin que les formulaires soient redimensionnables). Enfin, bien que le code de formulaire personnalisé puisse être un peu maladroit, vous pouvez l'implémenter sur un formulaire unique, puis hériter de tous les autres formulaires de votre application, ce qui en fait une technique très utile pour la personnalisation. -skinning une application entière.

+0

Honnêtement une approche très juste –

2

Ma tâche était de rendre la fenêtre active plus visible, brillante - que d'autres, les fenêtres inactives de l'application. App a de nombreuses fenêtres ouvertes, certaines modales, certaines modéles - et le parent MDI.

Vous pouvez utiliser quelque chose comme not-a-border - un cadre dans la zone client. Voici l'extrait de code, une partie d'une classe de base (peut être utilisé directement sous une forme):

#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 

Les champs statiques de la classe sont initialisés de la forme de paramètres d'application (classe) - donc, toutes les formes de l'application a le même comportement.

Espérons que cela aide quelqu'un.

+0

où puis-je trouver ce type WindowFrameType ?? – user1912383

Questions connexes