【问题标题】:Change border color and appearance for WinForms control更改 WinForms 控件的边框颜色和外观
【发布时间】:2018-01-25 12:02:50
【问题描述】:

当用户悬停标签时,它会在标签上添加top-borderbottom-border

类似这样的东西:http://ianlunn.github.io/Hover/ -> 边框过渡 -> 中心下划线。

但是,我只知道如何定义普通边框。我什至不能改变边框的颜色,他的宽度等等......

这是我目前所取得的成就:

designer.cs:

this.label1.BackColor = System.Drawing.SystemColors.ActiveCaption;
this.label1.Font = new System.Drawing.Font("Arial", 16F, System.Drawing.FontStyle.Bold);
this.label1.Location = new System.Drawing.Point(124, 187);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(217, 65);
this.label1.TabIndex = 0;
this.label1.Text = "Something Cool";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.label1.MouseHover += new System.EventHandler(this.label1_MouseHover);
this.label1.MouseLeave += new System.EventHandler(this.label1_MouseLeave);

cs:

private void label1_MouseHover(object sender, EventArgs e)
{
    label1.BorderStyle = BorderStyle.FixedSingle;
    label1.Font = new Font("Arial", 18, FontStyle.Bold);
}

private void label1_MouseLeave(object sender, EventArgs e)
{
    // initialize
    label1.BorderStyle = BorderStyle.None;
    label1.Font = new Font("Arial", 16, FontStyle.Bold);
}

【问题讨论】:

  • 这比你想象的要大得多。您必须将控件继承到您自己的控件中。接管Paint 处理程序,并自己绘制它。您必须响应所有用户输入并做出相应的反应,绘制您希望看到的一切。这将不是一个容易的项目。如果您仍有选择的余地,您会发现 WPF 使这类事情变得容易得多。
  • 虽然在WinForms 中做到这一点并不难。你根本不需要接触继承。
  • @L.Guthardt 嗨,谢谢。我做到了:ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle, Color.Red, ButtonBorderStyle.Solid);它确实触及了所有标签,但我希望它只在顶部和底部,我该如何实现?

标签: c# winforms


【解决方案1】:

首先我建议你使用label1_MouseEnter() 事件而不是label1_MouseHover() 事件。由于悬停事件在您悬停label1 时不断触发。这是不必要的,因为您将在输入标签时更改label1 的外观,并在您离开后将其更改回默认值。所以MouseEnter()是你的首选。

我们将定义一个bool 变量来检查是否在label1 周围绘制了一个环绕的边框外壳。我们在MouseEnter()MouseLeave() 事件中更改它的值。

bool changeBorder;

在这些事件中,我们将调用 label1.Refresh(),它会重绘控件,因此将触发 Paint() 事件。

private void label1_MouseEnter(object sender, EventArgs e)
{
    changeBorder = true;
    label1.Refresh();
}

private void label1_MouseLeave(object sender, EventArgs e)
{
    changeBorder = false;
    label1.Refresh();
}

现在我们验证是否绘制了一个新的特殊边框 shell。如果是这样,我们使用ControlPaint 类及其DrawBorder() 方法来绘制label1Rectangle 大小的自定义边框。您可以根据需要修改此边框。如果我们不想画这个特殊边框,我们画一个默认边框。什么只是有Form的Backcolor的颜色,所以看起来label1周围没有任何边框。

private void label1_Paint(object sender, PaintEventArgs e)
{
    if (changeBorder)
    {
        ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle,
                      Color.Red, 0, ButtonBorderStyle.Solid,
                      Color.Red, 2, ButtonBorderStyle.Solid,
                      Color.Red, 0, ButtonBorderStyle.Solid,
                      Color.Red, 2, ButtonBorderStyle.Solid);
    }
    else
        ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle, this.BackColor, ButtonBorderStyle.None);
    }

ControlPaint.DrawBorder() 的方法参数中注意0 而不是2矩形宽度ControlPaint.DrawBorder()参数如下:

  1. int leftWidth
  2. int topWidth
  3. int rightWidth
  4. int bottowmWidth

这就是为什么我将值0 设置为第一个和第三个,因此不会在右侧和左侧绘制边框。您可以根据自己的需要进行调整。

【讨论】:

  • 非常感谢!我完全理解你的代码和解释。我还有一个问题,是否可以将这些功能(label1_Paint & label1_MouseEnter & label1_MouseLeave)与所有标签一起使用?我的意思是,如果我有一些标签,我不想对每个标签都做所有这些。我希望这三个都能处理所有标签,那么我该怎么做呢?我想我应该触发进入或离开哪个标签,但是我该如何实现呢?谢谢!!!
  • 您必须订阅每个标签的每个myLabel_MouseEnter()myLabel_MouseLeave()myLabel_Paint() 事件。因为一旦在此特定控件上发生一项操作,只会触发一个特定事件。但是例如您可以编写一个所有Paint() 事件都会调用的方法。因此,您订阅了所有 Paint() 事件,但所有这些事件都调用您定义的相同 extern 方法。这个 extern 方法需要 PaintEventArgs e 作为方法参数才能将矩形绘制到特定控件。
  • 如果我理解正确,请制作一个接收 PaintEventArgs e 的通用 Paint 函数,并在每个 labelX_paint 中调用他并传递函数的 PaintEventArgs e。是的?再次感谢
  • 没错。我相信您也可以创建一个自定义控件:public class CustomLabel : Label。然后修改已经是这个类中的Paint 方法。此外,在您的代码中,从此类中删除命名空间。这样,该控件将显示在ToolBox 中,因此您可以像所有默认控件一样将控件拖放到Form 上。您仍然需要执行labelX.Refresh(),但您为此自定义控件类创建的每个标签都已经实现了边框绘制。你也可以像普通的Label 一样使用这个CustomLabel
猜你喜欢
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 1970-01-01
  • 2014-11-15
  • 2017-03-05
  • 1970-01-01
  • 2013-09-05
相关资源
最近更新 更多