Spurious/Incorrect .NET Form.Activated() Event
Notice: Using the "fix" below can result in the form's
Notice 2: I've added another version below.
A couple of new categories for this blog:
But, let's continue with the subject of this post: the
Quite a few years ago I created my own Metro-style form based on the idea of Microsoft's flat-style interface. Metro was approximately a couple of years away from release and there wasn't really any screenshots of what it would look like. I ploughed on with my version - including a break of a year because it took a long time to get it working correctly as working with forms that have their
The biggest issue was getting Windows to treat the borderless form as a true window; it just didn't give a crap about it. A quick way to tell if Windows regards a form as a true window is to minimise it to the taskbar. Does it immediately disappear from view? It's not a true window. Does it animate down into the taskbar? It's a true window.
There were two issues remaining (that I remember, anyway): restoring the window from its minimised state causes the window to gain an extra X number of pixels on its height. That's still an issue and seems random as to which form it affects. The fix I put in-place seems to work most of the time, but regardless, the child controls gain extra height with/without the form growing in size. Clearly more work to be done, there.
The second issue which I'm going to talk about here is the form's
It seems somewhat random when it happens, but here's how it generally goes:
This causes a problem in my particular case because I handle and expose the activation event via a
For example, here's a (currently work-in-progress) form that's active:
And here's that same form when it has become inactive:
As you can see, having the form become active when it actually isn't is confusing to the user. And extremely irritating to me.
My first quick go at fixing this seems to work; I'll have to keep testing it over the long term but it seems like it may have solved it. Not a fan that I have to do this in the first place, but what can ya do?
Have this at the first line(s) within the
Here's another version (see notice at top of this post):
I'm not sure if it's worth putting a check into the
Running Code on a Self-Contained Timer
A year without a post? Hrm. There is a post dated 2019 but it's in the
So here's a little post on running code on a timer; I don't know if C# can do this more elegantly, but I don't think VB can. Hence: this.
There have been far too many times I've wanted to run code that only displays something for a couple of seconds and then hides it. While simple enough, I really don't want to have to create a Timer component, instantiate it, run the code, and then tear it all down again. Just display a thing and then go away - that's all I want!
I couldn't even have a half-solution by instantiating and executing the Timer without having an explicit method for the Timer to call into when the time elapses, such as [note that all code formatting in this post is wonky; a lot of it isn't really fixable]:
I may make a specific extension method for this sort of thing but that's only tangibly why we're here and so will have to wait for another time.
So, today, I decided to try and get this sorted out. While it would probably have to be a Task, I wasn't entirely sure the best way of going about
And the enumeration:
The formatting is completely off in this post, so it doesn't look like that in actuality. I also have extension methods for certain things (eg. ensuring a value is appropriately clamped between a range) but I've replaced them with "pure code" versions above.
The above allows you to run code after a specific duration has elapsed, and optionally run additional code based on an event that occurs - all without having to create a separate Timer control that needs to be manually instantiated, hooked, and torn down. Again, this appears to be true for VB.
While not posted here, I have another version that uses a TimeSpan instead of a duration (meh; not a major thing) as it's "more appropriate", and a version that has the initial
Oh, an example? Right - yep, this is the basic version that only specifies the code that should be run after a duration has elapsed. This hides the (eg.) ToolStripLabel Verified OK! indicator after two seconds and is used to let the user know a thing they validated/verified/whatever is fine.
And another version that does the same as the above but also adds code that hides the visual indicator if the user clicks on it (this is a simplified version of code being used in Twitter Delitter).
And that's about it. While countless changes could be made, it would make this post unwieldy; I have a particular loathing for code examples that have extraneous fluff that does nothing but obfuscates what is being shown.
Use this code at your own risk, etc - I (mainly) use VB .NET so you probably shouldn't listen to me in the first place...