【问题标题】:Change ComboBox Border Color - Flash when SelectedIndex changed更改组合框边框颜色 - SelectedIndex 更改时闪烁
【发布时间】:2016-08-20 12:11:06
【问题描述】:

我只是想知道在 Windows 窗体中,当组合框更改时,我是否可以在组合框的边框周围创建一条红线?就像只是一闪而过的红色然后又消失了,只是为了表明它已经改变了。抓住用户的眼睛什么的。我将提供屏幕来代表我想要的。

如果可能的话,请告诉我在哪里可以找到它以获得一些信息。

无边框 更改时边框闪烁 一两秒后边界又消失了

【问题讨论】:

  • 你的意思是SelectedIndex > -1时要画边框吗?
  • @RezaAghaei 如果组合框发生变化,我想画一个边框。从索引 1 到 5 或从 3 到 9... 每当组合框更改时,我都想闪烁一个边框以表明它已更改。
  • 主要思想是使用计时器并绘制一段时间的边框。您可以使用不同的解决方案绘制边框。例如,您可以在ComboBox 上绘制边框,也可以在ComboBoxParent 上绘制边框。在我提出的答案中,我创建了一个MyComboBox 并添加了一个FlashHotBorder,可以调用它来闪烁边框。

标签: c# .net winforms combobox


【解决方案1】:

每当组合框发生变化时,我都想闪烁一个边框以表明它已发生变化。

主要思想是使用计时器并绘制一段时间的边框。您可以使用不同的解决方案绘制边框。例如,您可以(1)ComboBox 上绘制边框或(2) 您可以在ComboBoxParent 上绘制边框。

在我提出的答案中,我创建了一个MyComboBox 并添加了一个FlashHotBorder 方法,可以调用该方法来闪烁边框。我还添加了一个HotBorderColor 属性,可用于设置边框颜色。

ComboBox的闪烁边框

要为ComboBox 绘制边框,您可以处理ComboBoxWM_Paint 消息并为控件绘制边框。那么要让边框闪烁,就需要使用定时器,并开启和关闭边框一段时间:

我的组合框代码

我创建了一个FlashHotBorder 方法,您可以在SelectedIndexChanged 事件中调用它。此外,如果您总是想在所选索引更改时闪烁边框,您可以在OnSelectedIndexChanged 中调用它。我更喜欢在事件处理程序中调用它。这是实现:

using System.Drawing;
using System.Windows.Forms;
public class MyComboBox : ComboBox
{
    int flash = 0;
    private const int WM_PAINT = 0xF;
    private int buttonWidth = SystemInformation.HorizontalScrollBarArrowWidth;
    public Color HotBorderColor { get; set; }
    private bool DrawBorder { get; set; }
    Timer timer;
    public MyComboBox()
    {
        this.HotBorderColor = Color.Red;
        timer = new Timer() { Interval = 100 };
        timer.Tick += new System.EventHandler(timer_Tick);
    }
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if (m.Msg == WM_PAINT && this.DrawBorder)
            using (var g = Graphics.FromHwnd(this.Handle))
            using (var p = new Pen(this.HotBorderColor))
                g.DrawRectangle(p, 0, 0, this.Width - 1, this.Height - 1);
    }
    public void FlashHotBorder()
    {
        flash = 0;
        timer.Start();
    }
    void timer_Tick(object sender, System.EventArgs e)
    {
        if (flash < 10)
        {
            flash++;
            this.DrawBorder = !this.DrawBorder;
            this.Invalidate();
        }
        else
        {
            timer.Stop();
            flash = 0;
            DrawBorder = false;
        }
    }
    protected override void Dispose(bool disposing)
    {
        if (disposing) { timer.Dispose(); }
        base.Dispose(disposing);
    }
}

那么对于你想要闪现的每个组合的SelectedIndexChanged 事件使用这个事件处理程序就足够了:

private void myComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    var combo = sender as FlatCombo;
    if (combo != null)
        combo.FlashHotBorder();
}

【讨论】:

  • 喜欢的方式,边框闪烁:)
  • @Cleaven 如果您对答案有任何疑问,请告诉我:)
  • @RezaAghaei 谢谢你!这正是我想要的。完美的答案。非常感谢 :) 我会问我在实施时是否遇到任何问题。
  • @RezaAghaei 如果你想看的话,我发布了一个建议性的答案 :)
【解决方案2】:

您可以使用DrawRectangle 方法在comboBox 或任何其他控件 之外创建轮廓/绘制边框。

如果 SelectedIndex 范围条件满足,则边框将绘制在组合框之外,否则它将恢复到没有轮廓的原始状态。

bool changed = false;
private void Form1_Paint(object sender, PaintEventArgs e)
{
    if (changed)
    {
        Pen p = new Pen(Color.Red);
        Graphics g = e.Graphics;
        int diff = 1;
        g.DrawRectangle(p, new Rectangle(comboBox1.Location.X - diff, comboBox1.Location.Y - diff, comboBox1.Width + diff, comboBox1.Height + diff));
    }
}

而且,我在组合框的SelectedIndexChanged 事件上调用Form1_Paint 事件。

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    if (comboBox1.SelectedIndex >= 1 && comboBox1.SelectedIndex <= 9)
    {
        changed = true;
        this.Refresh();
    }
    else
    {
        changed = false;
        this.Refresh();
    }
}

                   大纲                                       没有大纲

【讨论】:

  • 我只是想知道你在哪里调用 Form1_Paint 方法,因为我试图这样做,但我的组合框根本没有检索到边框。
  • @Cleaven 右键单击您的表单以打开属性窗口。转到 Events 窗口,只需调用表单的Paint 事件:)
【解决方案3】:

所以我想出了这个。我认为这是最短和最简单的方法。如果您有任何建议,请随时发布或评论。感谢所有的帮助:)。

public partial class Form1 : Form
{
    private int tick = 0;
    public Form1()
    {
        InitializeComponent();
    }
    bool changed = false;        
    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {            
        if (changed == true)
        {
            changed = false;
            this.Refresh();
        }
        else
        {
            if(tick<3)
            {
                timer1.Enabled = true;
                timer1.Start();  
            }                          
            changed = true;
            this.Refresh();
        }
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        if (changed)
        {              
            Graphics g1 = e.Graphics;
            int diff = 1;
            Rectangle rect2 = new Rectangle(comboBox1.Location.X - diff, comboBox1.Location.Y - diff, comboBox1.Width + diff, comboBox1.Height + diff);
            using (LinearGradientBrush br = new LinearGradientBrush(rect2,Color.Red,Color.Blue,LinearGradientMode.Horizontal))
            {
                ColorBlend color_blend = new ColorBlend();
                color_blend.Colors = new Color[] { Color.Red, Color.Orange, Color.Yellow, Color.Lime, Color.Blue, Color.Indigo, Color.DarkViolet};
                color_blend.Positions = new float[] { 0 / 6f, 1 / 6f, 2 / 6f, 3 / 6f, 4 / 6f, 5 / 6f, 6 / 6f };
                br.InterpolationColors = color_blend;
                Pen p = new Pen(br, 10);
                e.Graphics.DrawRectangle(p, rect2);
            }                
        }
        else
        {
            Pen p = new Pen(Color.Transparent);
            Graphics g = e.Graphics;
            int diff = 1;
            g.DrawRectangle(p, new Rectangle(comboBox1.Location.X - diff, comboBox1.Location.Y - diff, comboBox1.Width + diff, comboBox1.Height + diff));
        }
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        if(tick<3)
        {
            comboBox1_SelectedIndexChanged(null, null);
            tick++;
        }
        else
        {
            timer1.Stop();
            tick = 0;
        }

    }     
}

【讨论】:

  • 知道如何使边框像彩虹色吗?
  • 1) 创建一个矩形var r= comboBox1.bounds,然后使用r.Inflate(2,2) 扩大或缩小一个矩形,它执行您正在使用diff 执行的工作。 2) 您需要使用FillRectangle 而不是DrawRectangle。轮换似乎也不错。 3) 目前该方法只能用于单个ComboBox。你有多少个组合框需要这样的功能?
  • @RezaAghaei 目前只有这个组合框,但如果它发生变化,我可以轻松创建一个方法,并将组合框的名称作为发件人传递......我认为这会起作用,应该不是吗?彩虹不是必需品,但我想既然我们讨论了这个主题,如果我们可以让它像画笔中的彩虹色一样,它可能是一段有用的代码?
  • 看看this post的彩虹效果。这是一个很好的例子,可以使用我在注释 1 中提到的技巧简单地应用于您的代码。
  • 关于多个组合框,是的,它也可以使用多个组合框,但可能会使您的代码混乱。使用继承或创建封装逻辑的扩展器组件对这种情况有好处。
猜你喜欢
  • 2016-01-06
  • 2021-02-09
  • 1970-01-01
  • 2021-09-03
  • 2016-04-24
  • 1970-01-01
  • 2010-09-09
  • 2017-03-05
  • 1970-01-01
相关资源
最近更新 更多