Domanda

Il pulsante "Apri" nella finestra di dialogo di apertura file utilizzata in alcune applicazioni Windows include una freccia a discesa con un elenco di opzioni aggiuntive, ovvero "Apri con...".

Non l'ho visto in tutte le applicazioni Windows, quindi potresti doverne provare alcune per ottenerlo, ma SQL Server Management Studio e Visual Studio 2005 mostreranno entrambi il pulsante in questo modo se vai al menu e scegli File->Apri->File...

Desidero utilizzare un pulsante come questo con un elenco integrato in una delle mie applicazioni, ma non riesco a trovare il controllo utilizzato da nessuna parte in Visual Studio.Dovrei chiarire che sto cercando quel pulsante specifico, non l'intera finestra di dialogo.qualche idea?

È stato utile?

Soluzione

Ho utilizzato la ricerca trascinabile in Spy++ (installata con VS) per esaminare il pulsante di apertura diviso nella finestra di dialogo di apertura file di VS.

Ciò ha rivelato che si tratta di un normale pulsante di Windows con uno stile che include BS_DEFSPLITBUTTON.Questa è una parola chiave magica che ti porta in posti interessanti, tra cui

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

e qui

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

Spero che questo ti aiuti.

MODIFICARE:

In realtà ho appena provato quel codice da CodePlex e crea un pulsante diviso, ma devi assicurarti di aver impostato FlatStyle del pulsante su "Sistema" anziché su "Standard" che è l'impostazione predefinita.Non mi sono preso la briga di collegare il materiale di gestione degli eventi per il menu a discesa, ma credo che questo sia coperto dal collegamento MSDN.

Naturalmente, questo è solo per Vista (ma non ha bisogno di Aero abilitato, nonostante il nome su codeplex): se hai bisogno del supporto del sistema operativo precedente, tornerai a disegnarlo da solo.

Altri suggerimenti

Me lo sono ricordato Ketarina ha un pulsante del genere.

Utilizzando Riflettore Ho trovato un ottimo controllo open source chiamato wyDay.SplitButton. wyDay.SplitButton

Penso che quello che stai cercando si chiami toolStripSplitButton.È disponibile solo in un toolStrip.Ma puoi aggiungere un toolStripContainer in qualsiasi punto del modulo e quindi inserire toolStrip e toolStripSplitButton all'interno del contenitore.

Non vorrai mostrare i grip, quindi ti consigliamo di impostare gripMargin = 0.Puoi anche impostare autosize=true in modo che la barra degli strumenti sia conforme al tuo pulsante.Il pulsante apparirà come un normale pulsante (ad eccezione della parte divisa) sul modulo.

Non ho familiarità con l'utilizzo di nessuno di questi, ma prova a cercare su msdn splitbutton o dropdownbutton.Penso che siano simili a quello che stai cercando.

Ecco la mia implementazione del pulsante diviso.Non disegna la freccia e il comportamento di messa a fuoco/non messa a fuoco è leggermente diverso.

Sia il mio che gli originali gestiscono gli stili visivi e hanno un bell'aspetto con Aero.

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

Non penso che ci sia un controllo integrato che possa farlo in .NET.Sto curiosando nella documentazione MSDN per il controllo pulsante standard di Windows, ma non sembra che sia lì.

Ho trovato un Articolo sul progetto Codice con un'implementazione personalizzata;questo potrebbe aiutare un po'.

Dato che ho trovato il controllo in Windows stesso, speravo di trovarlo già integrato da qualche parte in modo da non dover aggiungere nulla al mio codice base per usarlo.Ma il pulsante di divisione su questo link (trovato tramite il suggerimento msdn) sembra piuttosto promettente.

Lo proverò più tardi anch'io, ma non so quanto bene gestirà gli stili visivi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top