Fuzz Evans
Fuzz Evans

Reputation: 2943

How can I test which icon my notifyIcon is using?

I am having issues testing which icon my notifyIcon is using.

I have a notifyicon instantiated for my program. When the program runs I assign an icon to it in my code.

public Form1()
    {            
        InitializeComponent();
        notifyIcon1.Icon = Properties.Resources.LogoIcon;
    }

I have 2 buttons, one which starts my timer, and 1 which stops my timer. The timer event is suppose to check which icon is currently being used and switch it to the other option, but it doesn't work using my test.

Timer miniClock = new Timer();

    private void btnStartTimer_Click(object sender, EventArgs e)
    {           
        miniClock.Interval = 1000;
        miniClock.Tick += new EventHandler(MiniClockEventProcessor);
        miniClock.Start();
    }

    private void MiniClockEventProcessor(Object myObject, EventArgs myEventArgs)
    {
        if (notifyIcon1.Icon == Properties.Resources.AlertIcon)
        {
            notifyIcon1.Icon = Properties.Resources.LogoIcon;
        }
        else
            notifyIcon1.Icon = Properties.Resources.AlertIcon;

    }

    private void btnStopTimer_Click(object sender, EventArgs e)
    {
        miniClock.Stop();
        btnTest.Enabled = true;
    }

The frustrating part is when I start the timer, it will change the icon, but my test fails and it will only switch the icon in the else statement because there's no criteria to it except that it fails the if statement? How can I test which icon is currently being used, and then switch the icon to it's counterpart on the timer event call?

Upvotes: 0

Views: 492

Answers (2)

Ry-
Ry-

Reputation: 225281

The reason is that every time you access an object directly from Properties.Resources, it actually reads it anew and creates a fresh object. Since == will test by reference and the references are not equal, your test fails each time.

The solution is to cache it, which you should be doing regardless for efficiency:

private static readonly Icon LogoIcon = Properties.Resources.LogoIcon;
private static readonly Icon AlertIcon = Properties.Resources.AlertIcon;

public Form1()
{            
    InitializeComponent();
    notifyIcon1.Icon = LogoIcon;
}

and

Timer miniClock = new Timer();

private void btnStartTimer_Click(object sender, EventArgs e)
{           
    miniClock.Interval = 1000;
    miniClock.Tick += new EventHandler(MiniClockEventProcessor);
    miniClock.Start();
}

private void MiniClockEventProcessor(Object myObject, EventArgs myEventArgs)
{
    if (notifyIcon1.Icon == AlertIcon)
    {
        notifyIcon1.Icon = LogoIcon;
    }
    else
        notifyIcon1.Icon = AlertIcon;

}

private void btnStopTimer_Click(object sender, EventArgs e)
{
    miniClock.Stop();
    btnTest.Enabled = true;
}

Upvotes: 3

Tigran
Tigran

Reputation: 62265

I think it's easier to relay on some state then to Icon itself. I imagine that yo setup AlertIcon or LogonIcon, based on some event, or on some changed state notification. It's better to have somewhere the simple bool statevariable that indicates what happens.

For example , to explain what am I talking about, is a pseudocode :

private void MiniClockEventProcessor(Object myObject, EventArgs myEventArgs)
{
   if (!IsAlertState)
   {
       notifyIcon1.Icon = Properties.Resources.LogoIcon;
   }
   else
       notifyIcon1.Icon = Properties.Resources.AlertIcon;

}

private bool IsAlertState {get;set}

On recived alert the property IsAlertState = true.

Something like this.

Upvotes: 1

Related Questions