突出显示按钮而不更改Text,BackColor,Enabled?

时间:2013-10-30 10:10:48

标签: c# winforms button

突出显示按钮的好方法是什么?

使用或不允许使用:

  • 不要更改button.Text(必须保留旧文字)
  • 不要更改button.BackColor(按钮已经非常丰富多彩)
  • 不要更改button.Enabled(已使用但不够)

enter image description here

我们的想法是使用普通按钮来设置类似RadioButton组的东西。应该可以在眼角中轻松看到所选按钮。

我也有过的想法:

  • 边框/阴影:从未使用过,我真的不知道如何更改默认按钮阴影或单个按钮的边框样式。
  • 字体(下划线)
  • 图片(没试过)

3 个答案:

答案 0 :(得分:3)

通常情况下,应使用BackColor突出显示按钮,但如果您想要不同的内容,则可以轻松更改Border的外观。以下是实现边框外观的代码:

public class ButtonX : Button {
    GraphicsPath border = new GraphicsPath();
    int radius = 3;
    float borderWidth;
    Color borderColor = Color.Orange;
    bool _checked;
    public float BorderWidth {
        get { return borderWidth; }
        set {
            borderWidth = value;
            Invalidate();
        }
    }
    public Color BorderColor {
        get { return borderColor; }
        set {
            borderColor = value;
            Invalidate();
        }
    }
    public ButtonX() {
        BorderWidth = 4;
    }
    public bool Checked {
        get { return _checked; }
        set { 
            _checked = value;
            Invalidate();
        }
    }
    protected override void OnPaint(PaintEventArgs pevent) {
        base.OnPaint(pevent);
        if (Checked) {
            pevent.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            for (float f = BorderWidth; f >= 0.01f; f -= 1f)
            {
                using (Pen pen = new Pen(Color.FromArgb((int)(100 - 100 * f * f / (BorderWidth * BorderWidth)), borderColor), f))
                {
                    pen.LineJoin = LineJoin.Round;
                    pen.Alignment = PenAlignment.Center;
                    pevent.Graphics.DrawPath(pen, border);
                }
            }
        }
    }
    private void UpdateBorder() {
        border = new GraphicsPath();
        RectangleF rect = new RectangleF{Width = radius * 2, Height = radius * 2, X = BorderWidth/2, Y = BorderWidth/2};
        border.AddArc(rect, 180, 90);
        rect.X = ClientSize.Width - BorderWidth/2 - radius * 2 - 0.5f;            
        border.AddArc(rect, 270, 90);
        rect.Y = ClientSize.Height - BorderWidth/2 - radius * 2 - 0.5f;
        border.AddArc(rect, 0, 90);
        rect.X = BorderWidth / 2;
        border.AddArc(rect, 90, 90);
        border.CloseAllFigures();
    }
    protected override void OnSizeChanged(EventArgs e) {
        base.OnSizeChanged(e);
        UpdateBorder();
    }
}

注意:上面的ButtonX有一个名为Checked的属性,您可以将其更改为您想要的内容,这是确定highlighted border时间的属性显示。只需将其设置为true即可显示突出显示的边框。以下是一些屏幕截图(边框为8):

enter image description here

enter image description here

答案 1 :(得分:1)

我前段时间遇到过这个问题。以下解决方案突出显示颜色,保留原始颜色。您可以使用它来突出显示按钮背面颜色(但保留它)。否则,你应该拥有你的按钮并寻找一个好的机制来突出它(发光,边框等......)。希望它有所帮助。

public static Color HighLight(Color c)
{
    ColorRGB color = new ColorRGB(c);

    float newLValue = color.L;

    float highlightFactor = 0.25f; //from 0 to 1

    // change lightness
    if (color.L >= 0.5)
    {
        newLValue -= highlightFactor;
    }
    else
    {
        newLValue += highlightFactor;
    }

    ColorRGB highlighted = 
        FromHSLA(
        color.H, 
        color.S, 
        newLValue, 
        color.A);

    return Color.FromArgb(highlighted.A, highlighted.R, highlighted.G, highlighted.B);
}

public class ColorRGB
{
    public byte R;
    public byte G;
    public byte B;
    public byte A;

    public ColorRGB()
    {
        R = 255;
        G = 255;
        B = 255;
        A = 255;
    }

    public ColorRGB(Color value)
    {
        this.R = value.R;
        this.G = value.G;
        this.B = value.B;
        this.A = value.A;
    }
    public static implicit operator Color(ColorRGB rgb)
    {
        Color c = Color.FromArgb(rgb.A, rgb.R, rgb.G, rgb.B);
        return c;
    }
    public static explicit operator ColorRGB(Color c)
    {
        return new ColorRGB(c);
    }


    // Given H,S,L in range of 0-1
    // Returns a Color (RGB struct) in range of 0-255
    public static ColorRGB FromHSL(double H, double S, double L)
    {
        return FromHSLA(H, S, L, 1.0);
    }

    // Given H,S,L,A in range of 0-1
    // Returns a Color (RGB struct) in range of 0-255
    public static ColorRGB FromHSLA(double H, double S, double L, double A)
    {
        double v;
        double r, g, b;
        if (A > 1.0)
            A = 1.0;

        r = L;   // default to gray
        g = L;
        b = L;
        v = (L <= 0.5) ? (L * (1.0 + S)) : (L + S - L * S);
        if (v > 0)
        {
            double m;
            double sv;
            int sextant;
            double fract, vsf, mid1, mid2;

            m = L + L - v;
            sv = (v - m) / v;
            H *= 6.0;
            sextant = (int)H;
            fract = H - sextant;
            vsf = v * sv * fract;
            mid1 = m + vsf;
            mid2 = v - vsf;
            switch (sextant)
            {
                case 0:
                    r = v;
                    g = mid1;
                    b = m;
                    break;
                case 1:
                    r = mid2;
                    g = v;
                    b = m;
                    break;
                case 2:
                    r = m;
                    g = v;
                    b = mid1;
                    break;
                case 3:
                    r = m;
                    g = mid2;
                    b = v;
                    break;
                case 4:
                    r = mid1;
                    g = m;
                    b = v;
                    break;
                case 5:
                    r = v;
                    g = m;
                    b = mid2;
                    break;
            }
        }
        ColorRGB rgb = new ColorRGB();
        rgb.R = Convert.ToByte(r * 255.0f);
        rgb.G = Convert.ToByte(g * 255.0f);
        rgb.B = Convert.ToByte(b * 255.0f);
        rgb.A = Convert.ToByte(A * 255.0f);
        return rgb;
    }

    // Hue in range from 0.0 to 1.0
    public float H
    {
        get
        {
            // Use System.Drawing.Color.GetHue, but divide by 360.0F 
            // because System.Drawing.Color returns hue in degrees (0 - 360)
            // rather than a number between 0 and 1.
            return ((Color)this).GetHue() / 360.0F;
        }
    }

    // Saturation in range 0.0 - 1.0
    public float S
    {
        get
        {
            return ((Color)this).GetSaturation();
        }
    }

    // Lightness in range 0.0 - 1.0
    public float L
    {
        get
        {
            return ((Color)this).GetBrightness();
        }
    }
}

答案 2 :(得分:1)

可能您正在寻找切换按钮行为,但在组中是互斥的。您可以拥有一组复选框,并将其外观设置为按钮。但是你必须在代码中处理相互排斥的行为。

或者你可能有一组单选按钮并将其外观设置为按钮。

radioButton1.Appearance = Appearance.Button;