jjzjj

c# - ContextMenuStrip 向上或向下滚动按钮

coder 2024-06-04 原文

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

以下链接是一个VS2012 c#示例工程下载页面。 download example here

谢谢。

最佳答案

此解决方案枚举了 ContextMenuStrip 的子窗口。可能会出现有两个子窗口(滚动按钮)或零个子窗口的情况。

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

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

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);
        }

关于c# - ContextMenuStrip 向上或向下滚动按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29083903/

有关c# - ContextMenuStrip 向上或向下滚动按钮的更多相关文章

  1. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  2. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  3. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  4. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  5. ruby-on-rails - Rails 单选按钮 - 模型中多列的一种选择 - 2

    我希望用户从一个模型的三个选项中选择一个。即我有一个模型视频,可以被评为正面/负面/未知目前我有三列bool值(pos/neg/unknown)。这是处理这种情况的最佳方式吗?为此,表单应该是什么样的?目前我有类似的东西但显然它允许多项选择,而我试图将它限制为只有一个..怎么办? 最佳答案 如果要使用字符串列,让我们说rating。然后在你的表单中:#...#...它只允许一个选择编辑完全相同但使用radio_button_tag: 关于ruby-on-rails-Rails单选按钮-模

  6. ruby-on-rails - 如何从按钮或链接单击的 View 调用 Rails 方法 - 2

    基本上,我试图在用户单击链接(或按钮或某种类型的交互元素)时执行Rails方法。我试着把它放在View中:但这似乎没有用。它最终只是在用户甚至没有点击“添加”链接的情况下调用该函数。我也用link_to试过了,但也没用。我开始认为没有一种干净的方法可以做到这一点。无论如何,感谢您的帮助。附言。我在ApplicationController中定义了该方法,它是一个辅助方法。 最佳答案 View和Controller是相互独立的。为了使链接在Controller内执行函数调用,您需要对应用程序中的端点执行ajax调用。该路由应调用rub

  7. ruby-on-rails - 如何在 Rails 中添加禁用的提交按钮 - 2

    我在ruby​​表单中有一个提交按钮f.submitbtn_text,class:"btnbtn-onemgt12mgb12",id:"btn_id"我想在不使用任何javascript的情况下通过ruby​​禁用此按钮 最佳答案 添加disabled:true选项。f.submitbtn_text,class:"btnbtn-onemgt12mgb12",id:"btn_id",disabled:true 关于ruby-on-rails-如何在Rails中添加禁用的提交按钮,我们在St

  8. ruby-on-rails - 从 ActiveAdmin has_many 表单助手中删除 "Add new"按钮 - 2

    我在事件管理员编辑页面中有嵌套资源,但我只想允许管理员编辑现有资源的内容,而不是添加新的嵌套资源。我的代码看起来像这样:formdo|f|f.inputsdof.input:authorf.input:contentf.has_many:commentsdo|comment_form|comment_form.input:contentcomment_form.input:_destroy,as::boolean,required:false,label:'Remove'endendf.actionsend但它在输入下添加了“添加新评论”按钮。我怎样才能禁用它,并只为主窗体保留f.ac

  9. c# - C# 中的 Flatten Ruby 方法 - 2

    我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume

  10. ruby - 可以像在 C# 中使用#region 一样在 Ruby 中使用 begin/end 吗? - 2

    我最近从C#转向了Ruby,我发现自己无法制作可折叠的标记代码区域。我只是想到做这种事情应该没问题:classExamplebegin#agroupofmethodsdefmethod1..enddefmethod2..endenddefmethod3..endend...但是这样做真的可以吗?method1和method2最终与method3是同一种东西吗?还是有一些我还没有见过的用于执行此操作的Ruby惯用语? 最佳答案 正如其他人所说,这不会改变方法定义。但是,如果要标记方法组,为什么不使用Ruby语义来标记它们呢?您可以使用

随机推荐