组合框的下拉宽度的建议组合、宽度、建议

2023-09-04 00:09:17 作者:此男洧點⒉

我有一个组合框控件的形式。我选择了下拉式的属性下拉列表。我还设置下拉宽度为250。我已经设置了自动完成模式的建议和自动完成源listItems中。它的工作原理精绝当我点击下拉。但是当我输入事端,自动完成模式激活下拉里面有一个小的宽度。

任何帮助AP preciate。我想知道如何通过code增加了自动完成下降的幅度下降,使该列表项正确显示。我使用C#。

我曾问这几个月回来,但没有得到正确的答案。现在客户希望它坏:( ??

解决方案

 使用系统;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Drawing中;
使用了System.Runtime.InteropServices;
使用System.Text;
使用System.Windows.Forms的;

///<总结>
///重新presents与设置附加属性的组合框
///自动完成下拉窗口的大小。
///< /总结>
公共类ComboBoxEx:组合框
{
私人诠释acDropDownHeight = 106;
私人诠释acDropDownWidth = 170;


//<EditorBrowsable(EditorBrowsableState.Always),_

[可浏览(真),描述(的宽度,以像素为单位,自动完成下拉框),默认值(170)]
公众诠释AutoCompleteDropDownWidth
{
    {返回acDropDownWidth; }

    集合{acDropDownWidth =价值; }
}


//<EditorBrowsable(EditorBrowsableState.Always),_

[可浏览(真),描述(的高度,以像素为单位,自动完成下拉框),默认值(106)]
公众诠释AutoCompleteDropDownHeight
{
    {返回acDropDownHeight; }

    集合{acDropDownHeight =价值; }
}


保护覆盖无效OnHandleCreated(EventArgs的发送)
{
    base.OnHandleCreated(E);

    ACWindow.RegisterOwner(本);
}

#地区的嵌套类型:ACWindow

///&LT;总结&gt;
///提供的自动完成下拉窗口中的封装
///手柄和窗口过程。
///&LT; /总结&gt;
私有类ACWindow:NativeWindow的
{
    私人静态只读字典&LT; IntPtr的,ACWindow&GT; ACWindows;

    #地区赢API声明

    私人常量UInt32的WM_WINDOWPOSCHANGED = 0X47;

    私人常量UInt32的WM_NCDESTROY =为0x82;


    私人常量UInt32的SWP_NOSIZE =为0x1;

    私人常量UInt32的SWP_NOMOVE = 0X2;

    私人常量UInt32的SWP_NOZORDER =为0x4;

    私人常量UInt32的SWP_NOREDRAW = 0x8中;

    私人常量UInt32的SWP_NOACTIVATE = 0×10;


    私人常量UInt32的GA_ROOT = 2;
    私人静态只读目录&LT; ComboBoxEx&GT;业主;


    [的DllImport(user32.dll中)
    私人静态外部布尔EnumThreadWindows(INT dwThreadId,EnumThreadDelegate lpfn,IntPtr的lParam的);


    [的DllImport(user32.dll中)
    私人静态外部的IntPtr GetAncestor(IntPtr的的HWND,UInt32的gaFlags);


    [的DllImport(KERNEL32.DLL)
    私人静态外部INT GetCurrentThreadId();


    [的DllImport(user32.dll中)
    私人静态外部无效GetClassName(IntPtr的的HWND,StringBuilder的lpClassName,INT nMaxCount);


    [的DllImport(user32.dll中)
    私有静态的extern BOOL SetWindowPos(IntPtr的的HWND,IntPtr的hWndInsertAfter,INT X,INT Y,INT CX,INT CY,
                                            UINT和uFlags);


    [的DllImport(user32.dll中)
    私有静态的extern BOOL GetWindowRect(IntPtr的的HWND,裁判RECT升$ P $厘);

    #地区的嵌套类型:EnumThreadDelegate

    私人代表布尔EnumThreadDelegate(IntPtr的的HWND,IntPtr的lParam的);

    #endregion

    #地区的嵌套类型:RECT

    [StructLayout(LayoutKind.Sequential)
    私人结构R​​ECT
    {
        公共只读INT左;

        公共只读INT顶部;

        公共只读INT权利;

        公共只读INT底部;


        公共点位置
        {
            {返回新的点(左,上); }
        }
    }

    #endregion

    #endregion

    私人ComboBoxEx老板;

    静态ACWindow()
    {
        ACWindows =新字典&LT; IntPtr的,ACWindow&GT;();

        业主=新的名单,其中,ComboBoxEx&GT;();
    }


    ///&LT;总结&gt;
    ///创建从一个特定的窗口句柄新ACWindow实例。
    ///&LT; /总结&gt;
    私人ACWindow(IntPtr的手柄)
    {
        AssignHandle(手柄);
    }


    ///&LT;总结&gt;
    ///注册一个ComboBoxEx用于调整完成下拉窗口大小。
    ///&LT; /总结&gt;
    公共静态无效RegisterOwner(ComboBoxEx所有者)
    {
        如果((owners.Contains(所有者)))
        {
            返回;
        }

        owners.Add(业主);

        EnumThreadWindows(GetCurrentThreadId(),EnumThreadWindowCallback,IntPtr.Zero);
    }


    ///&LT;总结&gt;
    ///这个回调将接收处理的每个窗口,是
    ///与当前线程相关联。在这里,我们匹配下拉窗口名称
    ///要下拉窗口名称,并指定顶部窗口集合
    自动完成窗口///。
    ///&LT; /总结&gt;
    私有静态布尔EnumThreadWindowCallback(IntPtr的的HWND,IntPtr的lParam的)
    {
        如果((GetClassName(HWND)==自动建议下拉))
        {
            IntPtr的处理= GetAncestor(HWND,GA_ROOT);


            如果((!ACWindows.ContainsKey(手柄)))
            {
                ACWindows.Add(手柄,新ACWindow(句柄));
            }
        }

        返回true;
    }


    ///&LT;总结&gt;
    ///获取特定的窗口句柄类名。
    ///&LT; /总结&gt;
    私人静态字符串GetClassName(IntPtr的HREF)
    {
        VAR lpClassName =新的StringBuilder(256);

        GetClassName(HREF,lpClassName,256);

        返回lpClassName.ToString();
    }


    ///&LT;总结&gt;
    ///重写的NativeWindow的WndProc处理窗口时
    ///属性进行更改。
    ///&LT; /总结&gt;
    保护覆盖无效的WndProc(参考消息M)
    {
        如果((m.Msg == WM_WINDOWPOSCHANGED))
        {
            //如果业主尚未设置,我们需要找到ComboBoxEx的

            //与此下拉窗口相关联。我们通过检查是否做到这一点

            //下拉窗口的左上角的位置是内

            // ComboxEx客户端矩形。

            如果((所有者== NULL))
            {
                矩形ownerRect =默认(矩形);

                VAR acRect =新RECT();

                的foreach(ComboBoxEx CBO所有者)
                {
                    GetWindowRect(手柄,楼盘acRect);

                    ownerRect = cbo.RectangleToScreen(cbo.ClientRectangle);

                    如果((ownerRect.Contains(acRect.Location)))
                    {
                        店主= CBO;

                        打破; // TODO:可能不正确。为:退出对于
                    }
                }

                owners.Remove(业主);
            }


            如果(((主人!= NULL)))
            {
                SetWindowPos(拉手,IntPtr.Zero,-5,0,owner.AutoCompleteDropDownWidth,
                             owner.AutoCompleteDropDownHeight,SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
            }
        }


        如果((m.Msg == WM_NCDESTROY))
        {
            ACWindows.Remove(手柄);
        }


        base.WndProc(REF米);
    }
}

#endregion
}
 

这是我做的,它实际上作品真的很好。好找到答案atlast:)

I have a form which has a Combo Box Control. I have selected the drop down style property to DropDown. I have also set the DropDown Width to 250. I have set the auto complete mode to suggest and the auto complete source to listitems. it works absolutely fine when i click on the drop down. but when i type in somethin, the auto complete mode activates a drop down which has a small width.

在Excel表格中如何制作下拉菜单的图文教程

any help appreciate. i wanna know how to increase the width of the auto complete drop down via code so that the list items are viewed properly. I am using C#.

I had asked this a couple of months back but didn't get a proper answer. now the customer wants it bad :( ??

解决方案

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

/// <summary>  
/// Represents an ComboBox with additional properties for setting the   
/// size of the AutoComplete Drop-Down window.  
/// </summary>  
public class ComboBoxEx : ComboBox
{
private int acDropDownHeight = 106;
private int acDropDownWidth = 170;


//<EditorBrowsable(EditorBrowsableState.Always), _  

[Browsable(true), Description("The width, in pixels, of the auto complete drop down box"), DefaultValue(170)]
public int AutoCompleteDropDownWidth
{
    get { return acDropDownWidth; }

    set { acDropDownWidth = value; }
}


//<EditorBrowsable(EditorBrowsableState.Always), _  

[Browsable(true), Description("The height, in pixels, of the auto complete drop down box"), DefaultValue(106)]
public int AutoCompleteDropDownHeight
{
    get { return acDropDownHeight; }

    set { acDropDownHeight = value; }
}


protected override void OnHandleCreated(EventArgs e)
{
    base.OnHandleCreated(e);

    ACWindow.RegisterOwner(this);
}

#region Nested type: ACWindow

/// <summary>  
/// Provides an encapsulation of an Auto complete drop down window   
/// handle and window proc.  
/// </summary>  
private class ACWindow : NativeWindow
{
    private static readonly Dictionary<IntPtr, ACWindow> ACWindows;

    #region "Win API Declarations"

    private const UInt32 WM_WINDOWPOSCHANGED = 0x47;

    private const UInt32 WM_NCDESTROY = 0x82;


    private const UInt32 SWP_NOSIZE = 0x1;

    private const UInt32 SWP_NOMOVE = 0x2;

    private const UInt32 SWP_NOZORDER = 0x4;

    private const UInt32 SWP_NOREDRAW = 0x8;

    private const UInt32 SWP_NOACTIVATE = 0x10;


    private const UInt32 GA_ROOT = 2;
    private static readonly List<ComboBoxEx> owners;


    [DllImport("user32.dll")]
    private static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);


    [DllImport("user32.dll")]
    private static extern IntPtr GetAncestor(IntPtr hWnd, UInt32 gaFlags);


    [DllImport("kernel32.dll")]
    private static extern int GetCurrentThreadId();


    [DllImport("user32.dll")]
    private static extern void GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);


    [DllImport("user32.dll")]
    private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy,
                                            uint uFlags);


    [DllImport("user32.dll")]
    private static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

    #region Nested type: EnumThreadDelegate

    private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);

    #endregion

    #region Nested type: RECT

    [StructLayout(LayoutKind.Sequential)]
    private struct RECT
    {
        public readonly int Left;

        public readonly int Top;

        public readonly int Right;

        public readonly int Bottom;


        public Point Location
        {
            get { return new Point(Left, Top); }
        }
    }

    #endregion

    #endregion

    private ComboBoxEx owner;

    static ACWindow()
    {
        ACWindows = new Dictionary<IntPtr, ACWindow>();

        owners = new List<ComboBoxEx>();
    }


    /// <summary>  
    /// Creates a new ACWindow instance from a specific window handle.  
    /// </summary>  
    private ACWindow(IntPtr handle)
    {
        AssignHandle(handle);
    }


    /// <summary>  
    /// Registers a ComboBoxEx for adjusting the Complete Dropdown window size.  
    /// </summary>  
    public static void RegisterOwner(ComboBoxEx owner)
    {
        if ((owners.Contains(owner)))
        {
            return;
        }

        owners.Add(owner);

        EnumThreadWindows(GetCurrentThreadId(), EnumThreadWindowCallback, IntPtr.Zero);
    }


    /// <summary>  
    /// This callback will receive the handle for each window that is  
    /// associated with the current thread. Here we match the drop down window name   
    /// to the drop down window name and assign the top window to the collection  
    /// of auto complete windows.  
    /// </summary>  
    private static bool EnumThreadWindowCallback(IntPtr hWnd, IntPtr lParam)
    {
        if ((GetClassName(hWnd) == "Auto-Suggest Dropdown"))
        {
            IntPtr handle = GetAncestor(hWnd, GA_ROOT);


            if ((!ACWindows.ContainsKey(handle)))
            {
                ACWindows.Add(handle, new ACWindow(handle));
            }
        }

        return true;
    }


    /// <summary>  
    /// Gets the class name for a specific window handle.  
    /// </summary>  
    private static string GetClassName(IntPtr hRef)
    {
        var lpClassName = new StringBuilder(256);

        GetClassName(hRef, lpClassName, 256);

        return lpClassName.ToString();
    }


    /// <summary>  
    /// Overrides the NativeWindow's WndProc to handle when the window  
    /// attributes changes.  
    /// </summary>  
    protected override void WndProc(ref Message m)
    {
        if ((m.Msg == WM_WINDOWPOSCHANGED))
        {
            // If the owner has not been set we need to find the ComboBoxEx that  

            // is associated with this dropdown window. We do it by checking if  

            // the upper-left location of the drop-down window is within the   

            // ComboxEx client rectangle.   

            if ((owner == null))
            {
                Rectangle ownerRect = default(Rectangle);

                var acRect = new RECT();

                foreach (ComboBoxEx cbo in owners)
                {
                    GetWindowRect(Handle, ref acRect);

                    ownerRect = cbo.RectangleToScreen(cbo.ClientRectangle);

                    if ((ownerRect.Contains(acRect.Location)))
                    {
                        owner = cbo;

                        break; // TODO: might not be correct. Was : Exit For
                    }
                }

                owners.Remove(owner);
            }


            if (((owner != null)))
            {
                SetWindowPos(Handle, IntPtr.Zero, -5, 0, owner.AutoCompleteDropDownWidth,
                             owner.AutoCompleteDropDownHeight, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
            }
        }


        if ((m.Msg == WM_NCDESTROY))
        {
            ACWindows.Remove(Handle);
        }


        base.WndProc(ref m);
    }
}

#endregion
}

This is what I did and it actually works really well. Good to find an answer atlast :)

 
精彩推荐
图片推荐