Am I the only one who feels like, sometimes, I miss the most BASIC stuff?
I mean things like trying to set a textbox's contents...and scratching my head for an hour trying to figure out why I keep getting compile errors.
(ok, it was really only 30 minutes and about 3 google searches until I discovered the .Text property..)
Stuff that's apparently so basic everyone else absorbed it by osmosis. And I, coming along as an aging duffer with failing eyesight and mismatched socks (it's charming, really) struggle with trying to do something "X" way, when in all reality everyone else knows it's much easier to do it like "Y".
Case in point - updating text fields in a windows forms application in C# from another class.
Can't do it. Well, you can. I think. Sorta. All the examples I've found seem...well...ugly.
That is, it can be done, but there seems to be an inordinate amount of casting and fiddling that just screams to my unitiated self "THIS IS BRITTLE!! DON'T DO IT! BAD, BAD DEVELOPER!" The kind of code that gets featured in The Daily WTF.
Why am I doing this? Well, I'm a sadist. No, really. Well, kind of. I'm writing an app that requires some threading, as it launches loooong running jobs and I quickly discovered the foolishness of bogging down the main thread.
(no gui gui is no goody goody)
I want those threads to update the main form with status messages.
(Alive. Dead. Mostly Dead. Dead-as-the-proverbial-parrot.)
I tried using messaging, handlers, delegates. I really did. I even found a pretty helpful thread. And an awesome c#/.net threading tutorial. (full book text online, even!)
But alas, it seems that I was missing some vital brain cell. Couldn't understand it. Or perhaps I couldn't make the jump from all the examples assuming you were running the update handlers in the SAME FRICKIN CLASS you launched the thread from. When I attempted to, say, create an arraylist of objects that launch their own threads, getting the threads to communicate back seemed to require voodoo. And a dead chicken. And perhaps some eye of newt.
So I started decomposing. That is, making simpler and simpler test applications to see where my understanding (mental health...) was breaking down.
It finally got down to the fact that I'm not sure how to update a textbox from another class. (all together now..."What?!! That's easy!" Feel better? Good.)
Create a form. Insert a button and a text field. Click button. Button creates a new object and fires an method that's supposed to update the form's text field.
Can I access Form1.textBox1.text from the class method? Nooooooo... (yeah, I know there's a reason why. It just wasn't intuitive to me at the time)
Umm...ActiveForm.textBox1.text? Nope.
Err...Application.CurrentApplication.RunningApplication.
TheFormBloodyOnTheScreen.TextBox1.text?
According to the compiler, "Ha ha N()()B, not a chance!"
(those microsoft guys really have too much time on their hands)
I finally seem to have figured it out. I'm not sure if I'm going around my backside to scratch my ear, but this (seems to) work.
I had a brain flash this morning. All the stuff I'd done while threading with delegates. I thought "Hey, I wonder of my class method can call a delegate on the main form, passing in the object containing the message, and the delegate can call a helper method to update the text field."
It's still not as straightforward as I'd like. But it works. And seems to have some build-in robustness. Ie, the class throwing the update message doesn't give a rat's patoot what happens to it. Thus I've avoided tightly coupling the class to the form's structure. Ie, status text box can change names, helper function can change names. The only thing that can't change names is the delegate function.
Yeah, I know this is old hat to all you OO gurus. But as a little grasshopper, I'm happy with my small discovery.
Now to start diddling around with the threading piece again and see if I can make it all work.
Subscribe to:
Post Comments (Atom)

2 comments:
Did you ever find a good example on how to do this? (one that a mid-life - new to C# programmer could understand)?
I have a progress bar on a form - simply need another class (on another code page - if that matters) to pass something so I can get a progressbar++ on the form.
Sounds like it should be simple. I had the exact same situation and it was anything but...(though in my original situation, I wanted to update the status bar from a separate worker thread)
The best way to do this I found was using what are called delegates.
Essentially your sender creates an update object, tosses it into the messaging queue, the recipient has a handler defined for that message type, pulls it out and gives it to the message handler who then uses the data object therein to "do something". (update the status bar in your case)
Clear as mud? That's what I thought. I dug into this while trying to figure out multithreading. Painful.
However, it does seem to be the best way to get things done and it scales very well.
Try this: http://www.csharp-station.com/Tutorials/Lesson14.aspx
Google around for tutorials on delegates, events, handlers, and threading.
Sorry I don't have a quick-n-easy answer for you!
Post a Comment