【问题标题】:C# Winforms: User Control to blink labels in Legacy project NET 1.1C# Winforms:在旧项目 NET 1.1 中闪烁标签的用户控件
【发布时间】:2017-11-14 16:08:44
【问题描述】:

我正在尝试让用户控件闪烁标签。

我找到了这个example

using System.Diagnostics;
using System.Threading.Tasks;

private async void SoftBlink(Control ctrl, Color c1, Color c2, short CycleTime_ms, bool BkClr)
        {
            var sw = new Stopwatch(); sw.Start();
            short halfCycle = (short)Math.Round(CycleTime_ms * 0.5);
            while (true)
            {
                await Task.Delay(1);
                var n = sw.ElapsedMilliseconds % CycleTime_ms;  // ERROR #1
                var per = (double)Math.Abs(n - halfCycle) / halfCycle; 
                var red = (short)Math.Round((c2.R - c1.R) * per) + c1.R; // ERROR #2
                var grn = (short)Math.Round((c2.G - c1.G) * per) + c1.G; // ERROR #3
                var blw = (short)Math.Round((c2.B - c1.B) * per) + c1.B; // ERROR #4
                var clr = Color.FromArgb(red, grn, blw);
                if (BkClr) ctrl.BackColor = clr; else ctrl.ForeColor = clr;
            }
        }

由于我想在遗留项目 NET 1.1 中实现它,我需要转换上面的代码以使其工作,所以我在用户控制下实现了:

public class UCSoftBlink : System.Windows.Forms.Label
{
    /// <summary> 
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.Container components = null;
    private bool exit = false;
    private DateTime startTime = new DateTime();
    private TimeSpan elapsedTime = new TimeSpan();      
    private Timer timer = new Timer();
    private delegate void blinkingDelegate(Label lbl, Color clr1, Color clr2, short CycleTime_ms, bool bkClr);
    public static UCSoftBlink _ucSoftBlink;

    private UCSoftBlink()
    {
        // This call is required by the Windows.Forms Form Designer.
        InitializeComponent();

        timer.Tick += new EventHandler( timer_Tick );
        timer.Interval = (1000) * (1); 
        timer.Enabled = true; 
    }

    public static void StartBlinking(Label lbl, Color clr1, Color clr2, short CycleTime_ms, bool bkClr)
    {
        _ucSoftBlink = new UCSoftBlink();

        blinkingDelegate bd = new blinkingDelegate(_ucSoftBlink.Blink);
        bd.BeginInvoke(lbl, clr1, clr2, CycleTime_ms, bkClr, null, null);
    }

    public static void StopBlinking()
    {
        _ucSoftBlink.timer.Stop();
        _ucSoftBlink.exit = true;
    }

    private void Blink(Label lbl, Color clr1, Color clr2, short CycleTime_ms, bool bkClr)
    {
        _ucSoftBlink.timer.Start();
        _ucSoftBlink.startTime = DateTime.Now;          

        short halfCycle = (short)Math.Round(CycleTime_ms * 0.5);
        while (!exit)
        {
            System.Threading.Thread.Sleep(1000);
            short n = _ucSoftBlink.elapsedTime.TotalMilliseconds % CycleTime_ms; // ERROR #1
            double per = (double)Math.Abs(n - halfCycle) / halfCycle;
            short red = (short)Math.Round((clr2.R - clr1.R) * per) + clr1.R; ERROR #2
            short grn = (short)Math.Round((clr2.G - clr1.G) * per) + clr1.G; ERROR #3
            short blw = (short)Math.Round((clr2.B - clr1.B) * per) + clr1.B; ERROR #4
            Color clr = Color.FromArgb(red, grn, blw);

            if (bkClr) 
            {
                lbl.BackColor = clr; 
            }
            else
            {
                lbl.ForeColor = clr;
            }
        }

        Dispose(true);
    }

    private void timer_Tick(object sender, EventArgs e)
    { 
        _ucSoftBlink.elapsedTime = DateTime.Now - _ucSoftBlink.startTime;
    }

    /// <summary> 
    /// Clean up any resources being used.
    /// </summary>
    protected override void Dispose( bool disposing )
    {
        if( disposing )
        {
            if(components != null)
            {
                _ucSoftBlink.timer.Stop();
                _ucSoftBlink.timer.Tick -= timer_Tick; // // ERROR #5 I know this is possible in other version of NET (>=2.0).
                components.Dispose();
            }
        }
        base.Dispose( disposing );
    }

    #region Component Designer generated code
    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        components = new System.ComponentModel.Container();
    }
    #endregion
}

但我得到一些编译错误:

ERROR #1 error CS0197: Cannot pass 'My.Controls.UCSoftBlink.elapsedTime' as ref or out, because 'My.Controls.UCSoftBlink.elapsedTime' is a marshal-by-reference class
ERROR #1 error CS0029: Cannot implicitly convert type 'double' to 'short'
ERROR #2 error CS0029: Cannot implicitly convert type 'int' to 'short'
ERROR #3 error CS0029: Cannot implicitly convert type 'int' to 'short'
ERROR #4 error CS0029: Cannot implicitly convert type 'int' to 'short'
ERROR #5 error CS0654: Method 'sdpiu.Controles.UCSoftBlink.timer_Tick(object, System.EventArgs)' referenced without parentheses

我希望 StartBlinking、StopBlinking 是静态的,这样我就可以访问而无需实例化用​​户控件。

【问题讨论】:

  • 您为什么要在过时的遗留框架中工作,例如 .ent 1.1?
  • @MethodMan 这是一个遗留项目,我需要做一些修改。很快它将被迁移,但直到现在我需要进行修改。在此之前它需要维护。
  • “很快就会被迁移。”不,它不会,因为你一直在支撑它。
  • @DourHighArch 好吧,我知道这是一个非常古老的项目,但我的问题是让它以某种方式在 net 1.1 中工作,而不是迁移。因此,我非常感谢提供有关如何解决上述编译错误的想法。

标签: c# winforms user-controls .net-1.1


【解决方案1】:

您可以创建一个具有静态方法和属性的类来在另一个线程上处理此任务,并使用委托来安全地访问 GUI 控件, 这是一个基本方法,您可以根据自己的特定需求对其进行改进。

从您的用户控件调用类:

public void StartBlink()
{
    BlinkMe.BlinkedLabel = this.label1;
    // start blinking
    System.Threading.Thread t1 = new System.Threading.Thread(BlinkMe.Blink);
    t1.Start();
}
private void btnStopBlinking_Click(object sender, EventArgs e)
{
    // stop blinking
    BlinkMe.IsBlinking = false;
}

处理眨眼的类:

class BlinkMe
{
    public static Label BlinkedLabel;
    public static int milisec = 500;
    public delegate void BlinkDel();
    public static bool IsBlinking { get; set; } = true;

    public static void Blink()
    {

        while (IsBlinking)
        {
            System.Threading.Thread.Sleep(milisec);
            BlinkedLabel.Invoke(new BlinkDel(DoBLink));
        }
    }

    public static void DoBLink()
    {
        if (BlinkedLabel.BackColor != Color.Yellow)
        {
            BlinkedLabel.BackColor = Color.Yellow;
        }
        else
        {
            BlinkedLabel.BackColor = Color.Green;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 2012-05-22
    • 2011-12-24
    • 1970-01-01
    相关资源
    最近更新 更多