在我的应用程序中,这是一个WF项目,我有一个带有目录的组合框:
如果目录太大,用户将无法看到整个目录名称。
现在,在大多数应用程序中,我看到如果组合框或文本框的项目超出可见限制,则会显示/扩展完整字符串的项目/鼠标位置处显示一种小工具提示/ ballontip(完整目录名称我的意思是)
我的问题是如何做同样的事情,我不知道如何使用默认的工具提示。
更新:
我有这个用户控件,但打开下拉列表时变得非常慢,而当组合物项目过度移动时,项目之间的“导航”非常慢,就像我说的那样打开下拉列表也很慢单击以展开列表后单击列表。
我想像默认的组合框一样提高速度:
PS:我对C#
一无所知using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class ComboBoxTooltip : ComboBox
{
private DropdownWindow mDropdown;
public delegate void DropdownItemSelectedEventHandler(object sender, DropdownItemSelectedEventArgs e);
public event DropdownItemSelectedEventHandler DropdownItemSelected;
protected override void OnDropDown(EventArgs e)
{
// Install wrapper
base.OnDropDown(e);
// Retrieve handle to dropdown list
COMBOBOXINFO info = new COMBOBOXINFO();
info.cbSize = Marshal.SizeOf(info);
SendMessageCb(this.Handle, 0x164, IntPtr.Zero, out info);
mDropdown = new DropdownWindow(this);
mDropdown.AssignHandle(info.hwndList);
}
protected override void OnDropDownClosed(EventArgs e)
{
// Remove wrapper
mDropdown.ReleaseHandle();
mDropdown = null;
base.OnDropDownClosed(e);
OnSelect(-1, Rectangle.Empty, true);
}
internal void OnSelect(int item, Rectangle pos, bool scroll)
{
if (this.DropdownItemSelected != null)
{
pos = this.RectangleToClient(pos);
DropdownItemSelected(this, new DropdownItemSelectedEventArgs(item, pos, scroll));
}
}
// Event handler arguments
public class DropdownItemSelectedEventArgs : EventArgs
{
private int mItem;
private Rectangle mPos;
private bool mScroll;
public DropdownItemSelectedEventArgs(int item, Rectangle pos, bool scroll) { mItem = item; mPos = pos; mScroll = scroll; }
public int SelectedItem { get { return mItem; } }
public Rectangle Bounds { get { return mPos; } }
public bool Scrolled { get { return mScroll; } }
}
// Wrapper for combobox dropdown list
private class DropdownWindow : NativeWindow
{
private ComboBoxTooltip mParent;
private int mItem;
public DropdownWindow(ComboBoxTooltip parent)
{
mParent = parent;
mItem = -1;
}
protected override void WndProc(ref Message m)
{
// All we're getting here is WM_MOUSEMOVE, ask list for current selection for LB_GETCURSEL
Console.WriteLine(m.ToString());
base.WndProc(ref m);
if (m.Msg == 0x200)
{
int item = (int)SendMessage(this.Handle, 0x188, IntPtr.Zero, IntPtr.Zero);
if (item != mItem)
{
mItem = item;
OnSelect(false);
}
}
if (m.Msg == 0x115)
{
// List scrolled, item position would change
OnSelect(true);
}
}
private void OnSelect(bool scroll)
{
RECT rc = new RECT();
SendMessageRc(this.Handle, 0x198, (IntPtr)mItem, out rc);
MapWindowPoints(this.Handle, IntPtr.Zero, ref rc, 2);
mParent.OnSelect(mItem, Rectangle.FromLTRB(rc.Left, rc.Top, rc.Right, rc.Bottom), scroll);
}
}
// P/Invoke declarations
private struct COMBOBOXINFO
{
public Int32 cbSize;
public RECT rcItem;
public RECT rcButton;
public int buttonState;
public IntPtr hwndCombo;
public IntPtr hwndEdit;
public IntPtr hwndList;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)]
private static extern IntPtr SendMessageCb(IntPtr hWnd, int msg, IntPtr wp, out COMBOBOXINFO lp);
[DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)]
private static extern IntPtr SendMessageRc(IntPtr hWnd, int msg, IntPtr wp, out RECT lp);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
[DllImport("user32.dll")]
private static extern int MapWindowPoints(IntPtr hWndFrom, IntPtr hWndTo, [In, Out] ref RECT rc, int points);
}
答案 0 :(得分:1)
试试这个:
' Get the longest element
For Each elem As String In CBox1.Items
If elem.Length > auxCad.Length Then auxCad = elem
Next
' Get the size
iSize = CInt(CBox1.CreateGraphics.MeasureString(auxCad, CBox1.Font).Width) + 20
If iSize > CBox1.Width Then
'Show tooltip
End If
答案 1 :(得分:1)
嗯,你可以试试这个:
Dim LastSelectedItem As Int32 = -1
Private Sub ComboBoxTooltip_DropdownItemSelected(sender As Object, e As ComboBoxTooltip.DropdownItemSelectedEventArgs) _
Handles ComboBoxTooltip1.DropdownItemSelected
Dim SelectedItem As Int32 = e.SelectedItem
If SelectedItem <> LastSelectedItem Then
ToolTip1.Hide(sender)
LastSelectedItem = -1
End If
If SelectedItem < 0 OrElse e.Scrolled Then
ToolTip1.Hide(sender)
LastSelectedItem = -1
Else
If sender.Items(e.SelectedItem).Length > CInt(sender.CreateGraphics.MeasureString(0, sender.Font).Width) + 8 Then
LastSelectedItem = SelectedItem
ToolTip1.Show(sender.Items(SelectedItem).ToString(), sender, e.Bounds.Location)
End If
End If
End Sub
用户控制代码:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class ComboBoxTooltip : ComboBox
{
private DropdownWindow mDropdown;
public delegate void DropdownItemSelectedEventHandler(object sender, DropdownItemSelectedEventArgs e);
public event DropdownItemSelectedEventHandler DropdownItemSelected;
protected override void OnDropDown(EventArgs e)
{
// Install wrapper
base.OnDropDown(e);
// Retrieve handle to dropdown list
COMBOBOXINFO info = new COMBOBOXINFO();
info.cbSize = Marshal.SizeOf(info);
SendMessageCb(this.Handle, 0x164, IntPtr.Zero, out info);
mDropdown = new DropdownWindow(this);
mDropdown.AssignHandle(info.hwndList);
}
protected override void OnDropDownClosed(EventArgs e)
{
// Remove wrapper
mDropdown.ReleaseHandle();
mDropdown = null;
base.OnDropDownClosed(e);
OnSelect(-1, Rectangle.Empty, true);
}
internal void OnSelect(int item, Rectangle pos, bool scroll)
{
if (this.DropdownItemSelected != null)
{
pos = this.RectangleToClient(pos);
DropdownItemSelected(this, new DropdownItemSelectedEventArgs(item, pos, scroll));
}
}
// Event handler arguments
public class DropdownItemSelectedEventArgs : EventArgs
{
private int mItem;
private Rectangle mPos;
private bool mScroll;
public DropdownItemSelectedEventArgs(int item, Rectangle pos, bool scroll) { mItem = item; mPos = pos; mScroll = scroll; }
public int SelectedItem { get { return mItem; } }
public Rectangle Bounds { get { return mPos; } }
public bool Scrolled { get { return mScroll; } }
}
// Wrapper for combobox dropdown list
private class DropdownWindow : NativeWindow
{
private ComboBoxTooltip mParent;
private int mItem;
public DropdownWindow(ComboBoxTooltip parent)
{
mParent = parent;
mItem = -1;
}
protected override void WndProc(ref Message m)
{
// All we're getting here is WM_MOUSEMOVE, ask list for current selection for LB_GETCURSEL
Console.WriteLine(m.ToString());
base.WndProc(ref m);
if (m.Msg == 0x200)
{
int item = (int)SendMessage(this.Handle, 0x188, IntPtr.Zero, IntPtr.Zero);
if (item != mItem)
{
mItem = item;
OnSelect(false);
}
}
if (m.Msg == 0x115)
{
// List scrolled, item position would change
OnSelect(true);
}
}
private void OnSelect(bool scroll)
{
RECT rc = new RECT();
SendMessageRc(this.Handle, 0x198, (IntPtr)mItem, out rc);
MapWindowPoints(this.Handle, IntPtr.Zero, ref rc, 2);
mParent.OnSelect(mItem, Rectangle.FromLTRB(rc.Left, rc.Top, rc.Right, rc.Bottom), scroll);
}
}
// P/Invoke declarations
private struct COMBOBOXINFO
{
public Int32 cbSize;
public RECT rcItem;
public RECT rcButton;
public int buttonState;
public IntPtr hwndCombo;
public IntPtr hwndEdit;
public IntPtr hwndList;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)]
private static extern IntPtr SendMessageCb(IntPtr hWnd, int msg, IntPtr wp, out COMBOBOXINFO lp);
[DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)]
private static extern IntPtr SendMessageRc(IntPtr hWnd, int msg, IntPtr wp, out RECT lp);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
[DllImport("user32.dll")]
private static extern int MapWindowPoints(IntPtr hWndFrom, IntPtr hWndTo, [In, Out] ref RECT rc, int points);
}