Skip to main content
Home Forums Silverlight Programming Silverlight Controls and Silverlight Toolkit Prompts, Alerts, Dialogs, etc
6 replies. Latest Post by maxima120 on July 4, 2009.
(0)
acmilan5
Member
5 points
30 Posts
06-08-2009 3:19 PM |
Is there something coming in SL 3 that makes it simpler to prompt the user for information. e.g., The type of functionality that takes all of one line of code in javascript and other environments (e.g., prompt("What's your name?") ) but isn't possible in SL without rolling your own widget. Even with a custom dialog, you're not able to write linear code like
openDialog();doSomthingWithInformationEntered();
since processing continues with doSomthingWithInformationEntered as soon as the dialog opens (not after it's closed). So instead, you have to write an event handlers for the various buttons that might be on the dialog. Things get bloated and messy rather quickly.
pbromberg
Contributor
2114 points
368 Posts
06-08-2009 4:02 PM |
In Silverlight 3, ChildWindow does pretty much what you describe.
06-08-2009 5:07 PM |
Hello. Thank you for the pointer. ChildWindow does indeed do the new window part but unfortunately it doesn't address the problem of not being able to write linear code for the common scenario of prompting, alerts, etc.
From a writeup on the new control:
Another aspect of child windows that may not be obvious is that Show() is an asynchronous call. That is, it doesn't wait for the dialog to be dismissed; it returns immediately. That's why Show() returns void rather than a DialogResult. If you want to know how the dialog was dismissed (that is, what the DialogResult value is once the dialog is closed), you handle the dialog's Closed event and check DialogResult there.
More asynchronicity and event handlers. :-( Really makes for ugly, disjointed code in simple, common scenarios like prompting the user for a string value.
ksleung
5366 points
1,028 Posts
06-08-2009 5:45 PM |
I find that asynchronous code to be annoying when the logic is sequential. However, we do want asychronous code since you really shouldn't block the UI thread under most circumstances. Heck, when the UI thread is blocked, even background WCF calls are blocked!
Actually I recently found a compromise, which is that if the business logic is running on the background thread, you can do things in a synchronous manner. For example, I am now able to write code so that even WebClient can be executed synchronously.
maxima120
88 points
85 Posts
07-04-2009 9:35 AM |
ksleung:Actually I recently found a compromise, which is that if the business logic is running on the background thread, you can do things in a synchronous manner. For example, I am now able to write code so that even WebClient can be executed synchronously.
I tried to call business layer in separate thread synchronousliy but couldnt make it work.
07-04-2009 12:30 PM |
No I didn't write it (too busy with other things). I may write up something nice in a few days... I have a SyncWebClient which does synchronous web client with all the bells and whistles including async cancellation, timeout, etc, for my own project.
But let me just tell you the basic idea so you can do it yourself. It is rather simple.
(1) First, make sure you understand that if your function is running in the UI thread, it absolutely cannot block because (a) this is very bad for UI responsiveness, and (b) WebClient and GUI update and many other operations work only on the UI thread, and if you are blocking the UI thread they won't get the chance to finish and hence they won't get the chance to unblock, hence deadlock.
(2) Therefore, the only chance for a synchronous web client is if the call is running in a worker thread. You can block the worker thread as you wish. Just that somebody else needs to unblock your thread when it is done.
(3) To block/unblock, the best tool is ManualResetEvent. To block, you do this:
ManualResetEvent m = new ManualResetEvent(false);...m.WaitOne();
To unblock, you do this:
m.Set();
(4) So to make a synchronous web client, you create ManualResetEvent, start the request from the background, block the thread with WaitOne(), and in the Completed event, unblock the thread. Something like the following (not necessarily syntactically correct but the idea is here):
ManualResetEvent m = new ManualResetEvent(false);WebClient wc = new WebClient();wc.Completed += () => { ... m.Set();};wc.OpenRead(new Uri(uri), ...);m.WaitOne();
(5) You can abstract this into a SyncWebClient object, so you can do this:
SyncWebClient swc = new SyncWebClient();string result = swc.DownloadString(new Uri(uri), ...);
or this:
SyncWebClient swc = new SyncWebClient();Stream stream = swc.OpenRead(new Uri(uri), ...);
Again, the caveat is that THIS CAN ONLY BE CALLED FROM A WORKER THREAD. Keep this limitation in mind.
07-04-2009 9:07 PM |
Cool thank you