أي سيطرة هذه؟(زر "فتح" مع القائمة المنسدلة)

StackOverflow https://stackoverflow.com/questions/31090

  •  09-06-2019
  •  | 
  •  

سؤال

يتضمن الزر "فتح" الموجود في مربع حوار فتح الملف المستخدم في بعض تطبيقات Windows سهمًا منسدلًا يحتوي على قائمة من الخيارات الإضافية - وهي "فتح باستخدام ..".

لم أر هذا في كل تطبيقات Windows، لذلك قد تضطر إلى تجربة عدد قليل للحصول عليه، ولكن SQL Server Management Studio وVisual Studio 2005 سيعرضان الزر بهذه الطريقة إذا ذهبت إلى القائمة واخترت ملف->فتح->ملف...

أريد استخدام زر مثل هذا مع القائمة المضمنة في أحد تطبيقاتي، لكن لا يمكنني العثور على عنصر التحكم الذي يستخدمونه في أي مكان في الاستوديو المرئي.يجب أن أوضح أنني أبحث عن هذا الزر المحدد، وليس مربع الحوار بأكمله.أي أفكار؟

هل كانت مفيدة؟

المحلول

لقد استخدمت البحث القابل للسحب في Spy ++ (المثبت مع VS) لإلقاء نظرة على زر الانقسام المفتوح في مربع حوار فتح الملف في VS.

أظهر هذا أنه زر عادي للنوافذ بنمط يتضمن BS_DEFSPLITBUTTON.إنها كلمة رئيسية سحرية تنقلك إلى بعض الأماكن المثيرة للاهتمام، بما في ذلك

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

و هنا

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

آمل أن يساعدك هذا.

يحرر:

لقد قمت بالفعل بتجربة هذا الرمز من CodePlex وهو يقوم بإنشاء زر تقسيم - ولكن عليك التأكد من تعيين FlatStyle للزر على "System" بدلاً من "Standard" وهو الإعداد الافتراضي.لم أزعج نفسي بربط عناصر التعامل مع الحدث في القائمة المنسدلة، ولكن أعتقد أن هذا مشمول في رابط MSDN.

بالطبع، هذا مخصص لنظام التشغيل Vista فقط (لكنه لا يحتاج إلى تمكين Aero، على الرغم من الاسم الموجود في codeplex) - إذا كنت بحاجة إلى دعم سابق لنظام التشغيل، فستعود إلى رسمه بنفسك.

نصائح أخرى

تذكرت ذلك كيتارين لديه زر من هذا القبيل.

استخدام العاكس لقد وجدت عنصر تحكم مفتوح المصدر رائعًا يسمى wyDay.SplitButton. wyDay.SplitButton

أعتقد أن ما تبحث عنه يسمى ToolStripSplitButton.وهو متوفر فقط في ToolStrip.ولكن يمكنك إضافة ToolStripContainer في أي مكان في النموذج الخاص بك ثم وضع ToolStrip وtoolStripSplitButton داخل الحاوية الخاصة بك.

لن ترغب في إظهار المقابض لذا ستحتاج إلى ضبط هامش قبضتك = 0.يمكنك أيضًا ضبط الحجم التلقائي = صحيح بحيث يتوافق شريط الأدوات مع الزر الخاص بك.سيبدو الزر كزر عادي (باستثناء الجزء المقسم) في النموذج الخاص بك.

لم أكن على دراية باستخدام أي منهما، ولكن حاول البحث في msdn عن زر الانقسام أو الزر المنسدل.أعتقد أن هذه مشابهة لما تبحث عنه.

هذا هو تنفيذ زر الانقسام الخاص بي.إنه لا يرسم السهم، ويختلف سلوك التركيز/عدم التركيز قليلاً.

يتعامل كل من نسختي والنسخ الأصلية مع الأنماط المرئية وتبدو رائعة مع Aero.

مرتكز على 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();
        }
    }
}

لا أعتقد أن هناك عنصر تحكم مضمن يمكنه القيام بذلك في .NET.أنا أبحث في وثائق MSDN للتحكم القياسي في أزرار Windows، ولكن لا يبدو أنها موجودة.

لقد وجدت أ مقالة مشروع الكود مع تنفيذ مخصص؛هذا قد يساعد قليلا.

منذ أن وجدت عنصر التحكم في Windows نفسه، كنت آمل أن أجده مدمجًا في مكان ما بالفعل حتى لا أضطر إلى إضافة أي شيء إلى قاعدة التعليمات البرمجية الخاصة بي لاستخدامه.لكن زر الانقسام في هذا الرابط (تم العثور عليه عبر اقتراح msdn) يبدو واعدًا جدًا.

سأحاول ذلك لاحقًا بنفسي، لكني لا أعرف مدى نجاحه في التعامل مع الأنماط المرئية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top