【问题标题】:How to display tool tip over a transparent image placed on a Winform button如何在放置在 Winform 按钮上的透明图像上显示工具提示
【发布时间】:2019-04-12 04:23:28
【问题描述】:

我在按钮控件的右上角显示一个红色三角形的透明图标 (32x32),表示存在错误。此外,当用户将鼠标悬停在图标上时,会显示一个工具提示。

我已经能够显示图标和相关的工具提示。问题是一个透明的 32x32 图标,红色三角形只有 12x12。工具提示应该只在悬停在红色三角形而不是透明空间上时触发。

已尝试将三角形显示为按钮和图片框,但工具提示仍会在透明空间中触发。此外,错误提供程序首先被用作我要完成的目标。

UI 项:

  • 按钮控件:“btnAttachments”

  • 错误提供程序控件:“errManager”

    public class StackTest
    {
        private static Dictionary<string, Control> _errorMessages = new Dictionary<string, Control>();
    
        public StackTest()
        {
            InitializeComponent();
            InitErrors();
        }
        private void InitErrors()
        {
            _errorMessages.Clear();
            AddErrorControl(btnAttachments, "Missing file attachment(s).");
            //errManager.SetError(btnAttachments, "Missing file attachment(s)."); errManager.SetIconPadding(btnAttachments, -32);
        }
    
        private void AddErrorControl(Control control, string message = null, Enum selectedImage = null, EventHandler handler = null)
        {
            string name = "errFor" + control.Name;
            if (_errorMessages.ContainsKey(name)) { return; }
    
            Button errorIcon = CreateErrorControl(name, control);
            errorIcon.BackgroundImage = Theme.GetImage(selectedImage ?? eImages_OtherIcons.Error_TopRight_Small);
    
            //PictureBox errorIcon = CreateErrorControl2(name);
            //errorIcon.Image = Theme.GetImage(selectedImage ?? eImages_OtherIcons.Error_TopRight_Small);
            //errorIcon.Image = Bitmap.FromHicon((Theme.GetIcon(selectedImage ?? eImages_OtherIcons.Error_TopRight_Small)).Handle);
    
            if (null != handler) { errorIcon.Click += handler; }
            new ToolTip().SetToolTip(errorIcon, message);
            errorIcon.Tag = message;
    
            control.Controls.Add(errorIcon);
            control.Controls[name].Location = new Point(control.Width - errorIcon.Width +20 , 0 );
            _errorMessages.Add(name, errorIcon);
        }
    
        private Button CreateErrorControl(string name, Control control)
        {
            var errorIcon = new Button();
            errorIcon.Name = name;
            errorIcon.Size = new Size(32, 32);
            //errorIcon.Location = new Point(control.Width - errorIcon.Width, 0);
            errorIcon.Cursor = Cursors.Hand;
            errorIcon.FlatStyle = FlatStyle.Flat;
            errorIcon.BackColor = Color.Fuchsia;
            errorIcon.FlatAppearance.MouseDownBackColor = Color.Transparent;
            errorIcon.FlatAppearance.MouseOverBackColor = Color.Transparent;
            errorIcon.FlatAppearance.BorderSize = 0;
            errorIcon.Visible = false;
    
            return errorIcon;
        }
    
        private PictureBox CreateErrorControl2(string name) 
        {
            var errorIcon = new PictureBox();
            errorIcon.Name = name;
            errorIcon.Size = new Size(32, 32);
            errorIcon.Cursor = Cursors.Hand;
            errorIcon.BackColor = Color.Transparent;
            errorIcon.Visible = false;
    
            return errorIcon;
        }
    }
    

内置的错误提供程序控件实现了我想要复制的期望结果。这样做将允许更健壮的应用程序具有比错误提供程序提供的更多自定义功能。

【问题讨论】:

  • 尝试在三角形上放置 12x12 透明图像并将逻辑连接到图像。
  • 为什么不直接继承一个新类中的按钮并用它做任何你需要的事情呢?
  • 您可以创建按钮的位图(可能是绘制位图并存储在标签中)并使用 getpixel 来决定是否要显示工具提示。
  • @TaW 使用 GraphicsPath 在控件上绘制形状,在 MouseMove 上,GraphicsPath.IsVisible(e.Location)
  • 是的,另一种选择。

标签: c# image winforms


【解决方案1】:

根据 @TaW 的 GetPixel 建议,我做了进一步的研发,现在有了一些功能。图片框的标签包含要显示的工具提示消息。由于图片框是鼠标移动的“发送者”,因此很容易将图像提取回位图。

感谢大家的反馈。

首先,我将测试切换为使用带有 PictureBox 的 CreateErrorControl2 并添加到 MouseMove。

    private PictureBox CreateErrorControl2(string name) //, Control control)
    {
        var errorIcon = new PictureBox();
        errorIcon.Name = name;
        errorIcon.Size = new Size(32, 32);
        errorIcon.Cursor = Cursors.Default;
        errorIcon.BackColor = Color.Transparent;
        errorIcon.Visible = false;
        errorIcon.MouseMove += new MouseEventHandler(DisplayToolTip);

        return errorIcon;
    }

还添加了以下代码以支持 DisplayToolTip 方法。

    private bool _toolTipShown = false;

    private bool IsTransparent(PictureBox pb, MouseEventArgs e)
    {
        Color pixel = ((Bitmap)pb.Image).GetPixel(e.X, e.Y);
        return (0 == pixel.A && 0 == pixel.R && 0 == pixel.G && 0 == pixel.B);
    }

    private void DisplayToolTip(object sender, MouseEventArgs e)
    {
        Control control = (Control)sender;
        IsTransparent((PictureBox)control, e);
        if (IsTransparent((PictureBox)control, e))
        {
            _toolTip.Hide(control);
            _toolTipShown = false;
        }
        else
        {
            if (!_toolTipShown)
            {
                _toolTip.Show(control.Tag.ToString(), control);
                _toolTipShown = true;
            }
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    • 2016-12-29
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 2016-09-29
    • 2014-07-29
    相关资源
    最近更新 更多