ContextMenuStrip向上或向下滚动button

我目前正在开发一个Windows触摸应用程序。 一些winForm代码仍然存在。 正如你所看到的,滚动/箭头button的高度对于触摸button来说实在太小了。 有没有办法将高度增加到35/40像素?

你可以看到滚动按钮(箭头)的高度是如何的小

以下链接是一个VS2012 c#示例项目下载页面。 下载例子在这里

谢谢。

此解决方案枚举ContextMenuStrip的子窗口。 可能会发生有两个子窗口(滚动按钮)或零子窗口。

用于滚动按钮的控件是一个标签,默认使用一个小的9×5图像。 图像更新为更大的图像(使用Marlett字体),然后将AutoSize设置为true,这会导致标签自行调整大小。

编辑:将实现更改为扩展方法以获得更好的灵活性

 using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; namespace Opulos.Core.UI { ///<summary>Extension class to increase the size of the scroll up-down arrows on a drop down context menu or tool strip menu. The default up-down arrows are only 5 pixels high.</summary> public static class ToolStripEx { private static Hashtable htData = new Hashtable(); private class Data { public bool needsUpdate = true; public bool disposeLastImage = false; public ToolStrip toolStrip = null; public List<Image> currentImages = new List<Image>(); } public static void BigButtons(this ToolStrip toolStrip) { htData[toolStrip] = new Data() { toolStrip = toolStrip }; toolStrip.VisibleChanged += toolStrip_VisibleChanged; toolStrip.ForeColorChanged += toolStrip_ForeColorChanged; toolStrip.Disposed += toolStrip_Disposed; } static void toolStrip_Disposed(object sender, EventArgs e) { Data d = (Data) htData[sender]; if (d != null && d.currentImages != null) { foreach (var img in d.currentImages) img.Dispose(); d.currentImages = null; htData.Remove(sender); } } static void toolStrip_ForeColorChanged(object sender, EventArgs e) { Data d = (Data) htData[sender]; d.needsUpdate = true; UpdateImages(d); } static void toolStrip_VisibleChanged(object sender, EventArgs e) { Data d = (Data) htData[sender]; UpdateImages(d); } private static void UpdateImages(Data d) { if (!d.needsUpdate) return; d.toolStrip.BeginInvoke((Action) delegate { try { var list = GetChildWindows(d.toolStrip.Handle); if (list.Count == 0) return; List<Image> newImages = new List<Image>(); int k = 0; foreach (var i in list) { var c = Control.FromHandle(i) as Label; if (c != null && d.needsUpdate) { String glyph = (k == 0 ? "t" : "u"); using (Font f = new System.Drawing.Font("Marlett", 20f)) { Size s = TextRenderer.MeasureText("t", f); var oldImage = c.Image; c.Image = new Bitmap(s.Width, s.Height); newImages.Add(c.Image); // avoid disposing the default image // might cause problems, not sure if (d.disposeLastImage) oldImage.Dispose(); using (Graphics g = Graphics.FromImage(c.Image)) { using (Brush b = new SolidBrush(d.toolStrip.ForeColor)) g.DrawString(glyph, f, b, 0, 0); } c.AutoSize = true; } k++; } } if (newImages.Count > 0) { d.needsUpdate = false; d.disposeLastImage = true; d.currentImages = newImages; } } catch {} // protect against crash (just in case) }); } private static List<IntPtr> GetChildWindows(IntPtr parent) { List<IntPtr> result = new List<IntPtr>(); GCHandle listHandle = GCHandle.Alloc(result); try { EnumChildWindows(parent, enumProc, GCHandle.ToIntPtr(listHandle)); } finally { if (listHandle.IsAllocated) listHandle.Free(); } return result; } private delegate bool EnumChildProc(IntPtr hWnd, IntPtr lParam); private static EnumChildProc enumProc = new EnumChildProc(CallChildEnumProc); private static bool CallChildEnumProc(IntPtr hWnd, IntPtr lParam) { GCHandle gch = GCHandle.FromIntPtr(lParam); List<IntPtr> list = gch.Target as List<IntPtr>; if (list == null) throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>"); list.Add(hWnd); return true; } [DllImport("user32.dll")] private static extern bool EnumChildWindows(IntPtr hWndParent, EnumChildProc lpEnumFunc, IntPtr lParam); } } [STAThread] static void Main() { Application.EnableVisualStyles(); var cms = new ContextMenuStrip(); cms.BigButtons(); for (int i = 0; i < 20; i++) cms.Items.Add(new ToolStripMenuItem("Item " + i)); cms.MaximumSize = new Size(200, 400); Form f = new Form(); f.ContextMenuStrip = cms; Application.Run(f); }