winforms 在有限时间内更改Windows窗体文本框字体颜色

sy5wg1nm  于 2022-11-30  发布在  Windows
关注(0)|答案(5)|浏览(186)

我是C#和Windows窗体的新手,但这里有一个问题:如果布尔函数返回false,我想将名为 NameField 的文本框中的文本颜色更改为红色;
我试过使用NameField.ForeColor = System.Drawing.Color.Red;,但它永远变成红色,但我只想用几秒钟。这可能吗?

wkyowqbh

wkyowqbh1#

最简单的方法是使用Task.Delay。假设您希望在单击按钮时执行此操作:

private async void button1_Click(object sender, EventArgs e){
    try{
        NameField.ForeColor = System.Drawing.Color.Red;
        await Task.Delay(1000); // 1s
        NameField.ForeColor = System.Drawing.Color.Blue;
    }
     catch(Exception e){
          // handle exception
      }
}

计时器是另一种选择,但如果只希望它触发一次,则需要在事件处理程序中禁用计时器。Task.Delay的功能大致相同,但更简洁。
请记住try/catch,无论何时使用async void,您都希望捕获任何异常以确保它们不会丢失。
您可能还想考虑重复按下按钮。禁用按钮,或增加某个字段,并仅在字段的值与您设置颜色时的值相同时重置颜色。

nwlls2ji

nwlls2ji2#

在面向对象的类中,您了解到,如果您希望某个类与另一个类几乎相同,但只有一点功能不同,则应该派生。
因此,让我们创建一个从按钮派生的类,它可以更改颜色,并在一段时间后自动返回默认颜色。
按钮将有一个Flash方法,它将改变按钮的颜色。在一段指定的时间后,按钮将不闪烁。
为此,该类具有指定前景/背景颜色以及闪光时间的属性。

public class FlashOnceButton : Button
{
    private readonly Timer flashTimer
    private Color preFlashForeColor;
    private Color preFlashBackColor;

    public FlashOnceButton()
    {
         this.flashTimer = new Timer
         {
             AutoReset = false,
         };
         this.flashTime.Elapsed += FlashTimer_Elapsed;
    }

    public Color FlashBackColor {get; set;} = Color.Red;
    public Color FlashForeColor {get; set;} = base.ForeColor;
    public TimeSpan FlashTime {get; set;} = TimeSpan.FromSeconds(1);

    public bool IsInFlashState => this.Timer.Enabled;

    public void StartFlash()
    {
        // if already flashing, do nothing            
        if (this.IsInFlashState) return;

        // before changing the colors remember the current fore/back colors
        this.preFlashForeColor = this.ForeColor;
        this.preFlashBackcolor = this.BackColor;
        this.ForeColor = this.FlashForeColor;
        this.BackColor = this.FlashBackColor;

        this.Timer.Interval = this.FlashTime.TotalMilliseconds;
        this.Timer.Enabled = true;
    }
        
    private void FlashTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        // restore the colors:
        this.ForeColor = this.preFlashForeColor;
        this.BackColor = this.preFlashBackColor;
        this.flashTimer.Enabled = false;
    }
}

用法:编译后,您应该在visual studio工具箱中找到此类。因此,您可以使用visual studio设计器添加该类并设置属性。
您可以在InitializeComponent中找到它。
如果布尔函数返回false,我想将名为NameField的文本框中的文本颜色更改为红色;

public void OnBooleanChangedFalse()
{
    this.flashOnceButton1.StartFlash();
}

就这样了!
有一个怪癖:Timer类实现IDisposable,因此如果您停止窗体,则应Dispose它

public class FlashOnceButton : Button
{
    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            this.flashTimer.Dispose();
        }
    }
}

要确保在释放窗体时释放按钮,最简单的方法是将它定位到窗体的组件字段:

public void MyForm()
{
    InitializeComponent();   // this will create flashOnceButton1

    // make sure that the button is disposed when the Form is disposed:
    this.components.Add(this.flashOnceButton1);
}
nhaq1z21

nhaq1z213#

我有一个解决方案给你,但它是有点低效。请检查,让我知道。

int counter = 1;
        Timer timer1 = new Timer{Interval = 5000};
        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;

            if (myBoolMethod(counter))
            { 
                textBox1.ForeColor = System.Drawing.Color.Red;
                timer1.Tick += OnTimerEvent;
            }
            
            if (counter == 1)
                counter = 2;
            else
                counter = 1;
        }

        private void OnTimerEvent(object sender, EventArgs e)
        {
            textBox1.ForeColor = System.Drawing.Color.Black;
            timer1.Tick -= OnTimerEvent;
        }

        bool myBoolMethod(int param)
        {
           if(param % 2 == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
nom7f22z

nom7f22z4#

有几种方法可以处理这个问题。最直接的方法是使用Timer。如果你想在一段时间内保持颜色的变化,那么可以使用Stopwatch来捕捉经过的时间。

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private Timer _colorTimer; // Create a timer as a private field to capture the ticks
        private Stopwatch _swColor; // Create a stopwatch to determine how long you want the color to change
        private void Form1_Load(object sender, EventArgs e)
        {
            // Initialize fields
            _colorTimer = new Timer();
            _colorTimer.Interval = 10; // in milliseconds
            _colorTimer.Tick += ColorTimer_Tick; // create handler for timers tick event
            _swColor = new Stopwatch();

            NameField.Text = "Person Name"; // For testing purposes
        }

        // the timer will run on a background thread (not stopping UI), but will return to the UI context when handling the tick event
        private void ColorTimer_Tick(object sender, EventArgs e)
        {
            if(_swColor.ElapsedMilliseconds < 1000) // check elapsed time - while this is true the color will be changed
            {
                if(NameField.ForeColor != Color.Red)
                {
                    NameField.ForeColor = Color.Red;
                }
            } 
            else
            {
                // reset the controls color, stop the stopwatch and disable the timer (GC will handle disposal on form close)
                NameField.ForeColor = Color.Black;
                _swColor.Stop();
                _swColor.Reset();
                _colorTimer.Enabled = false;
            }
        }

        private void btnChangeColor_Click(object sender, EventArgs e)
        {
            // on button click start the timer and stopwatch
            _colorTimer.Start();
            _swColor.Start();
        }
    }
vsnjm48y

vsnjm48y5#

Using a Timer.
Example:
NameField.ForeColor = System.Drawing.Color.Red

Timer timer1 = new Timer
{
    Interval = 1000
};
timer1.Enabled = true;
timer1.Tick += new System.EventHandler(delegate (Object o, EventArgs a)
{  
    NameField.ForeColor = SystemColors.WindowText;
    timer1.Enabled = false;
});

相关问题