我有一个组合框控件的形式。我选择了下拉式的属性下拉列表。我还设置下拉宽度为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)
私人结构RECT
{
公共只读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.
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 :)
上一篇:使用C#.NET JSON web服务的制作NET、JSON、web
下一篇:用的OleDbConnection,Excel和连接池问题连接池、问题、OleDbConnection、Excel