2008-11-20 30 views
5

Me gustaría poder crear una ventana personalizada negra (con borde y controles) como la enviada como parte de la mezcla de expresiones, Twirl o Adobe Lightroom.Winforms: ¿cómo creo un borde de Windows personalizado y cierro/minimizo los botones?

¿Existe alguna forma de mejores prácticas para crear una ventana dibujada por el propietario?

Plataforma: C# y WindowsForms (cualquier versión)

+0

Aquí está el artículo para crear formularios de Windows personalizados usando solo paneles - [Creando formularios personalizados de Windows en C# utilizando paneles] (http://www.codeproject.com/Articles/1068043/Creating-Custom-Windows-Forms-in -Charla usando el panel) –

+0

Posible duplicado de [Custom titlebars/chrome en una aplicación de WinForms] (http://stackoverflow.com/questions/42460/custom-titlebars-chrome-in-a-winforms-app) –

Respuesta

4

Si las herramientas personalizadas-cromo no le proporcionan con el aspecto y la sensación que desea, este tipo de cosas es fácil hacer usted mismo en C#. Básicamente, crea una forma sin bordes (FormBorderStyle = None) y luego crea todos los controles y bordes usted mismo, colocando los controles donde los necesita (una etiqueta para la barra de título, botones de comando para cerrar y minimizar, etc.) y/o dibujar directamente en la superficie del formulario usando el objeto Graphics.

También debe implementar código para permitir que el formulario sea arrastrado por su barra de título "falso" (consulte this answer para obtener una muestra de cómo hacerlo). También puede tener que implementar su propio mecanismo de cambio de tamaño (si necesita que los formularios se puedan redimensionar).

Finalmente, aunque el código de forma personalizada puede ser un poco torpe, puede implementarlo en un solo formulario y luego tener todos los otros formularios heredados de este formulario, lo que lo convierte en una técnica muy útil para personalizar -skinning una aplicación completa.

+0

Honestamente un enfoque muy justo –

2

Mi tarea consistía en hacer que la ventana activa fuera más visible y brillante que en otras ventanas inactivas de la aplicación. La aplicación tiene muchas ventanas abiertas, algunas modales, otras no, y la principal de MDI.

Puede usar algo como no un borde: un marco dentro del área del cliente. Aquí está el fragmento de código, una parte de una clase base (se puede utilizar directamente en un formulario):

#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 

campos estáticos de la clase se inicializan de forma configuración de la aplicación (clase) - Entonces, todas las formas de la aplicación tiene el mismo comportamiento.

Espero que ayude a alguien.

+0

donde puedo encontrar este tipo WindowFrameType ?? – user1912383

Cuestiones relacionadas