Pregunta

El botón "Abrir" en el cuadro de diálogo para abrir archivos utilizado en ciertas aplicaciones de Windows incluye una flecha desplegable con una lista de opciones adicionales, concretamente "Abrir con...".

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

Quiero usar un botón como este con una lista incorporada en una de mis aplicaciones, pero no puedo encontrar el control que están usando en ningún lugar de Visual Studio.Debo aclarar que estoy buscando ese botón específico, no todo el diálogo.¿Alguna idea?

¿Fue útil?

Solución

Utilicé la búsqueda arrastrable en Spy++ (instalada con VS) para ver el botón de apertura dividida en el cuadro de diálogo de apertura de archivos de VS.

Esto reveló que es un botón normal de Windows 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

Espero que esto te ayude.

EDITAR:

De hecho, acabo de probar ese código de CodePlex y crea un botón dividido, pero debes asegurarte de haber configurado FlatStyle del botón en "Sistema" en lugar de "Estándar", que es el valor predeterminado.No me he molestado en conectar el manejo de eventos para el menú desplegable, pero creo que eso está cubierto en el enlace de MSDN.

Por supuesto, esto es solo para Vista (pero no necesita habilitar Aero, a pesar del nombre en codeplex); si necesita compatibilidad con un sistema operativo anterior, podrá volver a dibujarlo usted mismo.

Otros consejos

Me acordé de eso Ketarina Tiene un botón así.

Usando Reflector Encontré un excelente control de código abierto llamado wyDay.SplitButton. wyDay.SplitButton

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

No querrás mostrar los grips, por lo que deberás establecer gripMargin = 0.También puede configurar su tamaño automático = verdadero para que la barra 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.

No estoy familiarizado con el uso de ninguno de estos, pero intente buscar en msdn splitbutton o dropdownbutton.Creo que son similares a lo que estás buscando.

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

Tanto el mío como los originales manejan estilos visuales y lucen muy bien con Aero.

Residencia 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();
        }
    }
}

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

Encontré un Artículo del proyecto de código con una implementación personalizada;esto podría ayudar un poco.

Como encontré el control en Windows, esperaba encontrarlo integrado en algún lugar para no tener que agregar nada a mi código base para usarlo.Pero el botón de división en este enlace (encontrado a través de la sugerencia de msdn) parece bastante prometedor.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top