Having trouble hiding/showing MainForm

kaos_king

New member
Joined
Jun 15, 2016
Messages
4
Programming Experience
Beginner
Hi Guys,

I'm new to C# and I am re-doing a simple application that I did in VB in order to learn a little. This makes it easier as I already have the logic so I am essentially just converting each line. I'm sorry to register to ask this as I can normally just google and gather things I need but I am a little stumped on this (what I assume is an easy problem).

The application only has the MainForm and is hidden upon startup, it is then activated by pressing both the control keys. I did this in VB with the use of GetAsyncKeyState and a timer:

C#:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    Dim LCtrlKey, RCtrlKey, EscKey As Boolean
    LCtrlKey = GetAsyncKeyState(Keys.LControlKey)
    RCtrlKey = GetAsyncKeyState(Keys.RControlKey)
    EscKey = GetAsyncKeyState(Keys.Escape)
    If CapturedKeys = False Then
        If LCtrlKey And RCtrlKey = True Then
            CapturedKeys = True
            Me.Show()
        End If
    Else
        If EscKey = True Then
            btnClose_Click(sender, e)
        End If
    End If
End Sub

This has worked perfectly for over a year - although I'm not sure if that's the best way of achieving what I want but "it worked for me" :)

Now it comes to C# and I'm taking the same approach, this is the code I am testing with just trying to get the form to show/hide and it won't work from the timer. However a button on the form has no issue hiding it so I was thinking maybe its a threading problem, but if that's the case, why would it work in VB?

C#:
[COLOR=#0000ff][B]private[/B][/COLOR] [COLOR=#ff0000]void[/COLOR] [COLOR=#191970][B]OnTimedEvent[/B][/COLOR]([COLOR=#ff0000]object[/COLOR] source, [COLOR=#004085]ElapsedEventArgs[/COLOR] e)
{
    [COLOR=#008000]// If both control keys are pressed at the same time, show the form[/COLOR]
        [COLOR=#0000ff][B]if[/B][/COLOR] ([COLOR=#191970][B]GetAsyncKeyState[/B][/COLOR]([COLOR=#004085]Convert[/COLOR].[COLOR=#191970][B]ToInt16[/B][/COLOR]([COLOR=#004085][B]Keys[/B][/COLOR].[I]LControlKey[/I])) != [COLOR=#00008b]0[/COLOR] && [COLOR=#191970][B]GetAsyncKeyState[/B][/COLOR]([COLOR=#004085]Convert[/COLOR].[COLOR=#191970][B]ToInt16[/B][/COLOR]([COLOR=#004085][B]Keys[/B][/COLOR].[I]RControlKey[/I])) != [COLOR=#00008b]0[/COLOR])  {
            [COLOR=#008000]// MessageBox.Show(String.Format("2x ctrl: {0}", capturedKeys));[/COLOR]
            c[I]apturedKeys[/I] = [COLOR=#008b8b][B]true[/B][/COLOR];
            [COLOR=#8b0000]aForm[/COLOR].[COLOR=#8b0000]Show[/COLOR]();
        }
        [COLOR=#008000]// Or if Esc is pressed, hide the form[/COLOR]
        [COLOR=#0000ff][B]if[/B][/COLOR] ([COLOR=#191970][B]GetAsyncKeyState[/B][/COLOR]([COLOR=#004085]Convert[/COLOR].[COLOR=#191970][B]ToInt16[/B][/COLOR]([COLOR=#004085][B]Keys[/B][/COLOR].[I]Escape[/I])) != [COLOR=#00008b]0[/COLOR])  {
                [COLOR=#008000]// MessageBox.Show(String.Format("Esc: {0}", capturedKeys));[/COLOR]
                [I]capturedKeys[/I] = [COLOR=#008b8b][B]false[/B][/COLOR];
                [COLOR=#8b0000]aForm[/COLOR].[COLOR=#8b0000]Hide[/COLOR]();
        }
}

The commented out MessageBox's work fine along with the capturedKeys bool however I cannot get the form to show/hide from this timer. I'm afraid to ask but....what am I missing?
 
Based on the signature of that method, you're using a Timers.Timer in C# whereas you were using a Windows.Forms.Timer in VB. The Timers.Timer raises its Elapsed event on a secondary thread by default, which means that you can't safely do anything that modifies the UI. If you set the SynchronizingObject property then it will raise the event on the thread that owns that control but, if you do that, you may as well use a Windows.Forms.Timer in the first place.
 
Ah you are exactly right jmcilhinney. That stems from me having issues with Windows.Forms.Timers not ticking, following the advice here c# - Timer won't tick - Stack Overflow I switched to System.Timers.

Hmmm, I'll take another look at Forms.Timers and see if I can get it to work, as you say I might as well rather than messing with synchronization. I may well be back with another thread if I really can't get it going :nevreness:

/btw your .nut blogspot is ace, I read the managing data across forms when I started VB which helped me loads with threading
 
Okay it seems if I drag and drop the timer control from the toolbox and set that up, it doesn't work, however if I manually create it, it does!

Thank you for your help, I didn't realise system.timers created a new thread by default (I had also forgot about me switching from one timer to the other!).
 
Okay it seems if I drag and drop the timer control from the toolbox and set that up, it doesn't work, however if I manually create it, it does!

How are you creating the event handler when using the designer? Are you double-clicking on the Timer in the designer, using the Properties window or just typing/pasting the code in?
 
How are you creating the event handler when using the designer? Are you double-clicking on the Timer in the designer, using the Properties window or just typing/pasting the code in?

Sorry on the slow reply. When I did the project in VB I used VS2013, and now I'm using SharpDevelop (5.1.0) to do C# - but I don't think this has much to do with it, more so the difference in languages.

In VB I dragged and dropped the timer on the form (didn't touch the properties) and then set the interval and enabled the timer from Main, this worked without setting an event handler as (I assume) it is taken care of for me. Much like the other event handlers likes Form.Activated or Form.Shown, I realised this whilst learning C# that you must register the event handler (e.g. "this.Activated += this.MainForm_Activated;"), this I did not do when dragging and dropping the timer from the toolbox.

This is how I have it now, I assume that if I take away the first line then drag and drop a timer and call it 'aTimer', it would work? (I'm not on a pc I can test this with atm)

C#:
var aTimer = new Timer();
aTimer.Tick +=new EventHandler(OnTimedEvent);
aTimer.Interval=15;
aTimer.Start();
 
Back
Top Bottom