2008-08-27 32 views
8

El botón "Abrir" en el diálogo de archivo abierto utilizado en ciertas aplicaciones de Windows incluye una flecha desplegable con una lista de opciones adicionales, a saber, "Abrir con ...".¿Qué control es esto? (Botón "Abrir" con menú desplegable)

No he visto esto en todas las aplicaciones de Windows, por lo que puede que tenga que probar algunas para obtenerlo, pero SQL Server Management Studio y Visual Studio 2005 mostrarán el botón de esa manera si va al menú y elija Archivo-> Abrir-> Archivo ...

Quiero utilizar un botón como este con una lista incorporada en una de mis aplicaciones, pero no puedo encontrar el control que están utilizando en cualquier lugar en el estudio visual. Debo aclarar que estoy buscando ese botón específico, no el diálogo completo. ¿Alguna idea?

Respuesta

6

utilicé la búsqueda que pueden arrastrarse en Spy ++ (instalado con VS) para mirar el botón de apertura de división en el diálogo de abrir fichero de VS.

Esto reveló que es un botón de Windows normal con un estilo que incluye BS_DEFSPLITBUTTON.Esa es una palabra clave mágica que te lleva a algunos lugares interesantes, incluyendo

http://www.codeplex.com/windowsformsaero/SourceControl/FileView.aspx?itemId=212902&changeSetId=9930

y aquí

http://msdn.microsoft.com/en-us/library/bb775949.aspx#using_splits

la esperanza que esto le ayuda.

EDIT:

De hecho, he intentado simplemente que el código de CodePlex y lo hace crear un botón de división - pero usted tiene que asegurarse de que haya configurado el botón de FlatStyle a 'Sistema' en lugar de 'Estándar 'que es el predeterminado. No me molesté en conectar el manejo de eventos para el menú desplegable, pero eso está cubierto en el enlace de MSDN, creo.

Por supuesto, esto es solo Vista (pero no necesita Aero habilitado, a pesar del nombre en codeplex) - si necesita soporte de sistema operativo anterior, volverá a dibujarlo usted mismo.

1

No creo que haya un control incorporado que pueda hacerlo en .NET. Estoy hurgando en la documentación de MSDN para el control estándar del botón de Windows, pero no parece que esté allí.

Encontré un Code Project article con una implementación personalizada; esto podría ayudar un poco.

2

No estoy familiarizado con el uso de cualquiera de estos, pero intente buscar msdn para botón dividir o botón desplegable. Creo que esos son similares a lo que estás buscando.

4

Creo que lo que está buscando se llama toolStripSplitButton. Solo está disponible en una toolStrip. Pero puede agregar toolStripContainer en cualquier lugar de su formulario y luego colocar toolStrip y toolStripSplitButton dentro de su contenedor.

No querrá mostrar los agarres, por lo que querrá establecer su gripMargin = 0. También puede establecer su autosize = true para que la tira de herramientas se ajuste a su botón. El botón se verá como un botón normal (excepto por la parte dividida) en su formulario.

0

Como encontré el control en Windows mismo, esperaba encontrarlo incorporado en alguna parte, así que no tuve que agregar nada a mi código base para usarlo. Pero el botón de división en this link (encontrado a través de la sugerencia msdn) parece bastante prometedor.

Lo intentaré más tarde, pero no sé qué tan bien manejará los estilos visuales.

2

Aquí está mi implementación de botón dividido. No dibuja la flecha, y el comportamiento de enfoque/desenfoque es un poco diferente.

Tanto la mía como las originales manejan estilos visuales y se ven muy bien con Aero.

Con base en http://wyday.com/splitbutton/

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Windows.Forms; 
using System.Windows.Forms.VisualStyles; 
using System.Drawing; 
using System.ComponentModel; 
using System.Diagnostics; 

// Original: http://blogs.msdn.com/jfoscoding/articles/491523.aspx 
// Wyatt's fixes: http://wyday.com/splitbutton/ 
// Trimmed down and redone significantly from that version (Nick 5/6/08) 
namespace DF 
{ 
    public class SplitButton : Button 
    { 
     private ContextMenuStrip m_SplitMenu = null; 
     private const int SplitSectionWidth = 14; 
     private static int BorderSize = SystemInformation.Border3DSize.Width * 2; 
     private bool mBlockClicks = false; 
     private Timer mTimer; 

     public SplitButton() 
     { 
      this.AutoSize = true; 
      mTimer = new Timer(); 
      mTimer.Interval = 100; 
      mTimer.Tick += new EventHandler(mTimer_Tick); 
     } 

     private void mTimer_Tick(object sender, EventArgs e) 
     { 
      mBlockClicks = false; 
      mTimer.Stop(); 
     } 

     #region Properties 
     [DefaultValue(null)] 
     public ContextMenuStrip SplitMenu 
     { 
      get 
      { 
       return m_SplitMenu; 
      } 
      set 
      { 
       if (m_SplitMenu != null) 
        m_SplitMenu.Closing -= 
         new ToolStripDropDownClosingEventHandler(m_SplitMenu_Closing); 

       m_SplitMenu = value; 

       if (m_SplitMenu != null) 
        m_SplitMenu.Closing += 
         new ToolStripDropDownClosingEventHandler(m_SplitMenu_Closing); 
      } 
     } 

     private void m_SplitMenu_Closing(object sender, ToolStripDropDownClosingEventArgs e) 
     { 
      HideContextMenuStrip(); 
      // block click events for 0.5 sec to prevent re-showing the menu 

     } 

     private PushButtonState _state; 
     private PushButtonState State 
     { 
      get 
      { 
       return _state; 
      } 
      set 
      { 
       if (!_state.Equals(value)) 
       { 
        _state = value; 
        Invalidate(); 
       } 
      } 
     } 

     #endregion Properties 

     protected override void OnEnabledChanged(EventArgs e) 
     { 
      if (Enabled) 
       State = PushButtonState.Normal; 
      else 
       State = PushButtonState.Disabled; 

      base.OnEnabledChanged(e); 
     } 

     protected override void OnMouseClick(MouseEventArgs e) 
     { 
      if (e.Button != MouseButtons.Left) 
       return; 
      if (State.Equals(PushButtonState.Disabled)) 
       return; 
      if (mBlockClicks) 
       return; 

      if (!State.Equals(PushButtonState.Pressed)) 
       ShowContextMenuStrip(); 
      else 
       HideContextMenuStrip(); 
     } 

     protected override void OnMouseEnter(EventArgs e) 
     { 
      if (!State.Equals(PushButtonState.Pressed) && !State.Equals(PushButtonState.Disabled)) 
      { 
       State = PushButtonState.Hot; 
      } 
     } 

     protected override void OnMouseLeave(EventArgs e) 
     { 
      if (!State.Equals(PushButtonState.Pressed) && !State.Equals(PushButtonState.Disabled)) 
      { 
       if (Focused) 
       { 
        State = PushButtonState.Default; 
       } 

       else 
       { 
        State = PushButtonState.Normal; 
       } 
      } 
     } 

     protected override void OnPaint(PaintEventArgs pevent) 
     { 
      base.OnPaint(pevent); 

      Graphics g = pevent.Graphics; 
      Rectangle bounds = this.ClientRectangle; 

      // draw the button background as according to the current state. 
      if (State != PushButtonState.Pressed && IsDefault && !Application.RenderWithVisualStyles) 
      { 
       Rectangle backgroundBounds = bounds; 
       backgroundBounds.Inflate(-1, -1); 
       ButtonRenderer.DrawButton(g, backgroundBounds, State); 

       // button renderer doesnt draw the black frame when themes are off =(
       g.DrawRectangle(SystemPens.WindowFrame, 0, 0, bounds.Width - 1, bounds.Height - 1); 
      } 
      else 
      { 
       ButtonRenderer.DrawButton(g, bounds, State); 
      } 

      StringFormat format = new StringFormat(); 
      format.Alignment = StringAlignment.Center; 
      format.LineAlignment = StringAlignment.Center; 

      g.DrawString(Text, Font, SystemBrushes.ControlText, bounds, format); 
     } 

     private void ShowContextMenuStrip() 
     { 
      State = PushButtonState.Pressed; 
      if (m_SplitMenu != null) 
      { 
       m_SplitMenu.Show(this, new Point(0, Height), ToolStripDropDownDirection.BelowRight); 
      } 
     } 

     private void HideContextMenuStrip() 
     { 
      State = PushButtonState.Normal; 
      m_SplitMenu.Hide(); 
      mBlockClicks = true; 
      mTimer.Start(); 
     } 
    } 
} 
Cuestiones relacionadas