c# - 是否可以在 winforms 应用程序中定义左手组合框(即左侧的滚动条)?

标签 c# .net .net-3.5 combobox

我有一个 WinForms 应用程序正在带触摸屏的平板电脑上使用。该应用程序是使用 Visual Studio 2008 开发的,并使用了 .Net 框架的 3.5 版。我收到一个左撇子客户的请求,要求将 ComboBoxes 的滚动条放在下拉区域的左侧而不是右侧,但我不确定该怎么做,或者是否有可能做。有没有人以前这样做过或知道如何做到这一点?

最佳答案

这里有一个使用 Win32 API 调用来修改 ComboBox 的解决方案:http://www.codeguru.com/csharp/csharp/cs_controls/custom/print.php/c15261

大约一半,在“对齐 ComoBox 对象”标题下方。

页面末尾还有一些示例代码的链接。


示例 - 左侧滚动条和左侧文本

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace ComboBoxMod
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmMain());
        }
    }

    public partial class frmMain : Form
    {
        private ComboBoxMod.ComboBox cbTest; //this is the modified combo box
        private System.Windows.Forms.Button btnToggleAlign;
        private System.ComponentModel.IContainer components = null;

        public frmMain()
        {
            this.cbTest = new ComboBoxMod.ComboBox();
            this.btnToggleAlign = new Button();

            InitialiseComponent();

            for (int i = 0; i < 50; i++)
            {
                cbTest.Items.Add(i);
            }
        }

        void btnToggleAlign_Click(object sender, EventArgs e)
        {
            if (this.cbTest.ScrollAlignment == ComboBox.Alignment.Right) //If Right Aligned
            {
                this.cbTest.ScrollAlignment = ComboBox.Alignment.Left; //Set To Left
            }
            else
            {
                this.cbTest.ScrollAlignment = ComboBox.Alignment.Right; //Set To Right
            }
        }

        private void InitialiseComponent()
        {
            this.SuspendLayout();

            this.cbTest.FormattingEnabled = true;
            this.cbTest.Location = new System.Drawing.Point(12, 12);
            this.cbTest.Name = "cbTest";
            this.cbTest.Size = new System.Drawing.Size(180, 21);
            this.cbTest.TabIndex = 0;

            this.btnToggleAlign.Location = new System.Drawing.Point(12, 42);
            this.btnToggleAlign.Name = "btnScrollAlign";
            this.btnToggleAlign.Size = new System.Drawing.Size(180, 23);
            this.btnToggleAlign.TabIndex = 0;
            this.btnToggleAlign.Text = "Toggle Scrollbar Alignment";
            this.btnToggleAlign.UseVisualStyleBackColor = true;
            this.btnToggleAlign.Click += new EventHandler(btnToggleAlign_Click);

            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(200, 75);

            this.Controls.Add(this.cbTest);
            this.Controls.Add(this.btnToggleAlign);

            this.Name = "frmMain";
            this.Text = "frmMain";
            this.ResumeLayout(false);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
    }

    public class ComboBox : System.Windows.Forms.ComboBox //Inherits ComboBox
    {
        [DllImport("user32", CharSet = CharSet.Auto)]
        public extern static int GetWindowLong(IntPtr hwnd, int nIndex); //Retrieve Info About Specified Window

        [DllImport("user32")]
        public static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong); //Change An Attribute Of Specified Window

        [DllImport("user32.dll")]
        public static extern int GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi); //Retrieve Info About Specified Combo Box


        [StructLayout(LayoutKind.Sequential)]
        public struct COMBOBOXINFO //Contains ComboBox Status Info
        {
            public Int32 cbSize;
            public RECT rcItem;
            public RECT rcButton;
            public ComboBoxButtonState caState;
            public IntPtr hwndCombo;
            public IntPtr hwndEdit;
            public IntPtr hwndList;
        }


        [StructLayout(LayoutKind.Sequential)] //Describes Width, Height, And Location Of A Rectangle
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        public enum ComboBoxButtonState //Determines Current State Of ComboBox
        {
            STATE_SYSTEM_NONE = 0,
            STATE_SYSTEM_INVISIBLE = 0x00008000,
            STATE_SYSTEM_PRESSED = 0x00000008
        }

        /// <summary> 
        /// Alignment Enum For Left & Right
        /// </summary> 
        public enum Alignment
        {
            Left = 0,
            Right = 1
        }

        /// <summary> 
        /// Align ScrollBar 
        /// </summary> 
        public Alignment ScrollAlignment
        {
            get
            {
                return Scroll; //Get Value
            }
            set
            {
                if (Scroll == value) //If Not Valid Value
                    return;

                Scroll = value; //Set Value
                AlignScrollbar(); //Call AlignScroll Method
            }
        }

        private const int GWL_EXSTYLE = -20; //ComboBox Style
        private const int WS_EX_RIGHT = 4096; //Right Align Text 
        private const int WS_EX_LEFTSCROLLBAR = 16384; //Left ScrollBar
        private const int WS_EX_RIGHTSCROLLBAR = 128; //Right ScrollBar

        private IntPtr handle; //Handle Of ComboBox
        private Alignment Scroll; //Alignment Options For ScrollBar


        public ComboBox()
        {
            handle = CASGetHandle(this); //Get Handle Of ComboBox
            Scroll = Alignment.Right; //default alignment
        }

        /// <summary>
        /// Retrieves ComboBox Handle
        /// </summary>
        /// <param name="CASCombo"></param>
        /// <returns></returns>
        public IntPtr CASGetHandle(ComboBox CASCombo)
        {

            COMBOBOXINFO CASCBI = new COMBOBOXINFO(); //New ComboBox Settings Object
            CASCBI.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(CASCBI); //Call In Correct Size
            GetComboBoxInfo(CASCombo.Handle, ref CASCBI); //Obtain Handle
            return CASCBI.hwndList; //Return Handle
        }

        /// <summary>
        /// Align The ComboBox ScrollBar
        /// </summary>
        private void AlignScrollbar()
        {
            if (handle != IntPtr.Zero) //If Valid Handle
            {
                int style = GetWindowLong(handle, GWL_EXSTYLE); //Get ComboBox Style
                switch (Scroll)
                {
                    case Alignment.Left:
                        style = WS_EX_LEFTSCROLLBAR; //Align ScrollBare To The Left
                        break;
                    case Alignment.Right:
                        style =  WS_EX_RIGHTSCROLLBAR; //Align ScrollBare To The Right
                        break;
                }
                SetWindowLong(handle, GWL_EXSTYLE, style); //Apply On ComboBox
            }
        }
    }
}

关于c# - 是否可以在 winforms 应用程序中定义左手组合框(即左侧的滚动条)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8003530/

相关文章:

c# - 生成 CPU 缓存未命中时的性能

c# - 如何安全地拆分字符串?

c# - 仅运行 .Net 2.0 与 3.5 我错过了什么?

c# - 如果当前副本正在使用中,则打开文件的卷影副本

c# - 如何在 Windows Phone 8 上获得 WP7 风格的 ANID?

c# - 在 Windows 上用 C# 加载 linux 动态库 (.so)

c# - 即使应用程序未聚焦,也可以 Hook /检测 Windows 语言更改

C#无法匹配Html特殊字符

c# - 使用官方 C# 驱动程序更新 MongoDB 中的嵌入式文档(2 级深)

c# - 您可以在没有 Range 对象的情况下在 C# Interop.Excel 中运行 .Formula 吗?