【问题标题】:c# Draw rectangle around control when hoveredc#鼠标悬停时在控件周围绘制矩形
【发布时间】:2016-02-09 13:53:23
【问题描述】:

我正在重写 Control 类的 OnPaint 方法来创建表情符号。表情符号已创建。但是当它悬停时,我要在它周围添加一个矩形。

public class EmoticonControl : Control
{
    public EmoticonControl(string unicode, Image image)
    {
        this.unicode = unicode;
        this.image = image;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics graphics = e.Graphics;
        Rectangle clipRectangle = e.ClipRectangle;
        graphics.DrawImage(this.image, 0, 0, this.Size.Width, this.Size.Height);

        // When hovered
        Brush brush = new SolidBrush(this.selectedColor);
        graphics.FillRectangle(new SolidBrush(selectionColor), clipRectangle);
        graphics.DrawRectangle(new Pen(selectionBorderColor), clipRectangle.X, clipRectangle.Y, clipRectangle.Width - 1, clipRectangle.Height - 1);
        //
    }
    private string unicode;
    private Image image;

    private Color selectedColor = SystemColors.Highlight;
    private Color selectionColor = Color.FromArgb(50, 0, 0, 150);
    private Color selectionBorderColor = SystemColors.Highlight;
}

【问题讨论】:

  • 我看不懂这段代码。画笔在哪里使用(在“悬停时”评论之后)?

标签: c# winforms


【解决方案1】:

您可以使用UIElement.IsMouseOver 属性来了解您的控件是否悬停。

protected override void OnPaint(PaintEventArgs e)
{
    Graphics graphics = e.Graphics;
    Rectangle clipRectangle = e.ClipRectangle;
    graphics.DrawImage(this.image, 0, 0, this.Size.Width, this.Size.Height);

    // When hovered
    if (IsMouseOver)
    {
        Brush brush = new SolidBrush(this.selectedColor);
        graphics.FillRectangle(new SolidBrush(selectionColor), clipRectangle);
        graphics.DrawRectangle(new Pen(selectionBorderColor), clipRectangle.X, clipRectangle.Y, clipRectangle.Width - 1, clipRectangle.Height - 1);
    }
}

【讨论】:

    【解决方案2】:

    原版

    这应该适合你:

    public class EmoticonControl : Control
    {
        public EmoticonControl(string unicode, Image image)
        {
            this.unicode = unicode;
            this.image = image;
        }
    
        // Set hover, request invalidation:
        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            hover = true;
            this.Invalidate();
        }
    
        // Unset hover, request invalidation:
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            hover = false;
            this.Invalidate();
        }
    
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;
            Rectangle clipRectangle = e.ClipRectangle;
            graphics.DrawImage(this.image, 0, 0, this.Size.Width, this.Size.Height);
    
            // Only do this when hovering:
            if (hover)
            {
                Brush brush = new SolidBrush(this.selectedColor);
                graphics.FillRectangle(new SolidBrush(selectionColor), clipRectangle);
                graphics.DrawRectangle(new Pen(selectionBorderColor), clipRectangle.X, clipRectangle.Y, clipRectangle.Width - 1, clipRectangle.Height - 1);
            }
        }
    
        // Added flag to track hover status:
        private bool hover = false;
    
        private string unicode;
        private Image image;
    
        private Color selectedColor = SystemColors.Highlight;
        private Color selectionColor = Color.FromArgb(50, 0, 0, 150);
        private Color selectionBorderColor = SystemColors.Highlight;
    }
    

    更新版本:

    (包括对原始代码的一些“最佳实践”修复)

    public class EmoticonControl : Control
    {       
        public EmoticonControl(string unicode, Image image)
        {
            this.unicode = unicode;
            this.image = image;
        }
    
        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            hover = true;
            this.Invalidate();
        }
    
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            hover = false;
            this.Invalidate();
        }
    
        protected override void OnPaint(PaintEventArgs e)
        {
            DrawImage(e.Graphics);
            DrawSelectionRectangle(e.Graphics);
        }
    
        private void DrawSelectionRectangle(Graphics graphics)
        {
            if (hover)
            {
                using (var brush = new SolidBrush(selectionColor))
                {
                    graphics.FillRectangle(brush, this.ClientRectangle);
                }
                using (var pen = new Pen(selectionBorderColor))
                {
                    graphics.DrawRectangle(pen,
                        new Rectangle()
                        {
                            Width = (this.Width - 1),
                            Height = (this.Height - 1)
                        });
                }
            }
        }
    
        private void DrawImage(Graphics graphics)
        {
            if (image != null) graphics.DrawImage(
                this.image, 0, 0, this.Size.Width, this.Size.Height);
        }
    
        private bool hover = false;
        private Image image;
        private string unicode;
    
        private Color selectionColor = Color.FromArgb(50, 0, 0, 150);
        private Color selectionBorderColor = SystemColors.Highlight;
    }
    

    【讨论】:

    • 我已经尝试过这一步,但没有成功。 this.Invalidate(); 使代码完美。谢谢!
    • 没问题。我还注意到您的代码中还有其他一些小问题,例如在绘制图像时缺少null 检查,在图形对象上缺少using 语句......你介意我发布更新吗?很少有更正/建议?
    【解决方案3】:

    您可能需要在鼠标离开和输入事件中设置一个标志,然后检查绘图事件中的标志,如下所示:

    If(hover)
    {
        ControlPaint.DrawBorder(e.Graphics,this.DisplayRectangle,Color.Red,ButtonBorderStyle.Solid)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 2012-12-29
      • 2011-11-09
      • 1970-01-01
      • 2012-05-10
      相关资源
      最近更新 更多