Silverlight fire an event then fire another even a second later - silverlight

Is there a way to do something like this?
Background:
I have a button click. When the button is clicked I try to show a "loading" message, run a bunch of code that does some UI work and then dismiss the "loading" message. It takes anywhere from a few seconds to 20 seconds usually. At the moment the loading message doesn't show at all and the UI freezes until the code in my button click is done.
I've read about Background Worker and dispatcher, but haven't been able to get it to work. I'm not sure if it's because the code in the button click calls all sorts of other code (including 3rd party stuff), but I haven't been able to get it to run correctly. It all still works, but it still freezes the UI and the loading message doesn't appear.
So, I am wondering if there is another way around this. Is it possible to set it up so that on the button click I only show the loading message and then a second or so later fire another event that executes my long running process? That way the UI will still freeze for some seconds, but at least it will show a "loading" message.

You should be able to do this with a Dispatcher.BeginInvoke call.
private void ButtonClick(object sender, EventArgs e)
{
ShowMyLoadingMessage(); // your code, not sure what it is
Dispatcher.BeginInvoke(() =>
{
CallMyLongRunningCode(); // again, not sure what this is
HideMyLoadingMessage();
}
}
I don't believe this is the best solution since it is running on the UI thread, but it should do what you are asking.
What is the long running code doing that takes 20 seconds?

Related

Click event not firing with Backbone & jQuery

I'm using Backbone in an app & running into an situation where events are not firing.
My View, maps to a dialog interface containing several controls (a text area, a couple radio buttons, etc.) and a save button. I'm defining the following events:
events: {
'input': 'onchange',
'change': 'onchange',
'click .save': 'save',
'click .cancel': 'cancel',
},
Each time any form element in the dialog changes, I fire onchange, which performs some validation and either enables or disables the save button.
In the 'normal' flow, everything works properly. I fill out the textarea, click an option on the radio button, and then click save. My work is saved properly.
In an alternative flow, I try to click save while my cursor is still in the text area, and nothing happens. Then, if I click on the save button a second time, the form saves correctly. I've tried setting a breakpoint at the very beginning of the save method, and confirmed that it is not called during the first button click, and is then called correctly with the second button click.
I've tried to make a minimal example as a jsFiddle to demonstrate the issue, but I can't isolate the buggy behavior.
What could be preventing the click event and save function the first time I click the button? Do you have any tips or recommendations for helping debug an issue like this?
Update: Using a Javascript Profiler
I went back and used a profiler to dig in on what's happening. Here was my process:
Set up page for test, with everything filled in except the primary textarea
Start profiler
Type a letter into the textarea and wait for onchange handlers to fire, which is evidenced by Save button becoming enabled
Wait several seconds
Click Save - nothing happens
Stop profiler
And here's my profile:
What's interesting is that there's a clear flurry of activity when the onchange handlers fire, seen as a visible spike in the flame chart. However, when I click save the first time, there is no javascript execution captured at all! Very curious...

updating UI in windows phone 7

In method that is working in the background, i have two important lines :
createPopup();
MessageBox.Show(sth);
more lines
more lines
createPopup() just creates a popup, adds a grid as a child and shows popup.
My question is, why first shows up messageBox, then shows up Popup, which appears after all lines in this method done ? How could I make this popup to show before all lines in this method will be done ?
All the UI changes are normally queued up and will be shown at once on the screen.
And this does not include MessageBox. So it shows up immediately and prevents the execution, until user clicks on Ok. Hence eventhough your popUP is first executed, it will be shown in the UI only after the MessageBox.
For your problem, Try placing your MessageBox.Show(something) in a separate thread.
createPopup();
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("some message");
});
more lines
more lines
Give it a try. I am not sure whether it solves your problem or not as I dnt know the code in createPopUp() method.
Creating the pop-up, does not actually draw it on the screen until the Layout event. If you want to ensure that the pop-up has been drawn before you display the pop-up, attach an event handler to the pop-up's LayoutUpdated event and display the message box from within that event handler. Be sure to detach the event handler as well or you will see multiple message boxes.
public InitPage()
{
Popup popup = new Popup();
popup.LayoutUpdated += popup_LayoutUpdated;
LayoutRoot.Controls.Add(popup);
}
void popup_LayoutUpdated(object sender, object e)
{
popup_LayoutUpdated -= popup_LayoutUpdated;
MessageBox.Show("hello");
}

WPF updating the UI with a certain delay

I have a slideshow application where i want to wait a certain amount of seconds, then show my front page, then wait again, then show next page, and so on. My problem is that when i use Thread.Sleep in between, the UI arent updated, it just sits there waiting and i only see my last control (after the full amount of time has passed (i.e all the sleeps). Any solutions for doing this?
Thread.Sleep(1000);
ChangeContent(new FrontPage());
Thread.Sleep(5000);
ChangeContent(new HtmlPage());
Pre WPF i would just use the Application.DoEvents.
Use a DispatcherTimer.

Silverlight click event registered a second time before first event completed

I have a button which launches a "modal dialog" - it just creates a transparent grid covering everything, with the "dialog" created on top of that.
However I have a strange issue - if I double/triple click the button really fast (or add some delay in the event code), the button click event is executed multiple times, creating multiple overlapping modal dialogs. If the first action in my event is to disable the button (IsEnabled=false) it seems to prevent this.
My guess is that Silverlight is being multithreaded with input - it is not only recording the second click in another thread (while the button's click event is running), but it is jumping the gun by evaluating which control should be the target before the previous event has finished executing. Even though that event alters what control is at those mouse coordinates, it doesn't matter.
Does anyone know anything about this behavoir, or a way around it? If I have something like a save window, where the user clicks a save button, a blocking grid ("Saving...") is placed up while it saves, and then the whole "window" is closed, I'd like to avoid the user being able to queue up multiple save event clicks (this could lead to unpredictable program behavoir).
If you've ever worked with WinForms or WPF, this is expected behavior. Your button is broadcasting its Click event until your modal dialog covers it up. Unfortunately, there is some amount of time between your first click and when the modal dialog covers the button which allows multiple clicks to the original button.
You have two solution choices:
Disable the button after the first click and then re-enable after the modal dialog returns. You've already mentioned that this works.
Write code in the Event Handler of the button to determine if a modal dialog is already being displayed. This way, you're putting the responsibility in one location rather than splitting it up (disabling and re-enabling the button). This would be my preferred solution.
I think what you're seeing is the behaviour of Silverlight's routed events.
You can set the Handled property of the event arguments to true to prevent the event from bubbling.

How can I make a 'Partially' modal dialog?

Is there a way to start off showing a dialog modally, but then instead of hiding it, to keep it visible while changing it to a non-modal dialog?
I want to show a dialog, blocking the method that shows the dialog. Then when the user clicks the 'Finish' button on the dialog I want:
The dialog to remain visible.
Control to return to the method that showed the dialog.
I've achieved this result by running the dialog on a separate STA thread, and using an event to block the main UI thread until 'Finish' is pressed, but there's a catch to this method: you can click on the close button of the 'main' window while the dialog is visible, and the main window closes when the dialog is hidden.
Update
Thanks for the responses so far. Sorry - it looks like I got the balance wrong between too much background and not enough.
The form is effectively a modal 'wizard' dialog - it appears, sits in front of the main app modally, and then is hidden. So as far as the user's concerned there's no non-standard weirdness going on. The only difference is that the dialog is driven from a series of callbacks from the UI thread, so I don't think making it truly modal (via a call to ShowDialog) for its lifetime would work. The first callback must show the dialog, and then block while the user sets their preferences via the dialog UI. After that, the dialog stays visible and displays a progress bar page while various other callbacks are made from the UI thread. Eventually the form is hidden. The user isn't interacting with the main window while the form is up. As far as they're concerned, it should appear to be 100% modal wrt the main UI thread.
(The form is a dialog for a Visual Studio wizard - these are driven from a series of callbacks on the UI thread). An alternative would be to show the dialog, hide it, immediately show a topmost 'progress' form instead and then hide that, but I think showing a single dialog is more seamless an experience for the user.
Again - sorry for the confusion!
Perhaps you want to rethink your interaction model? How are you going to explain this to your users? They have an internalized model of how computer programs work, and you better have a very good reason to break that. They know about modal dialogs, they know about non-modal dialogs, they know about inspectors. Choose one, and apply it.
Modal dialogs are made for short-time interaction. They should not block exiting the application. The user is in control of the interaction, the program only provides the minimum of restrictions needed.
[after the explanation, replaced]
What's wrong with showing the progress bar in the modal dialog? Start processing once ok
is clicked, disabling all buttons, only keeping the cancel button active? If it takes a long time, the user might want to abort the action. Only close the dialog when you're finished processing.
You could use a modeless dialog then have your main UI check if the user has clicked the Finished button. If the modeless dialog is open but Finished hasn't been clicked then don't respond to any users actions in the main form...
This is just a terrible idea - it's completely non-standard behavior and you're going to jump through all kinds of hoops to get something working that is just going to horribly confuse your users.
Like most of the other answers here stated, you're implement non-standard UI elements that will be confusing to most users.
If the dialog remains visible just to provide read-only access to the data, then why not have dialog window close normally and open a side-bar window in your application with the data from the dialog window?
If the dialog remains visible to allow the users to continue making updates in it, then perhaps, it shouldn't be modal to begin with.
Point is, there's a couple different ways you can accomplish your task without breaking standard UI metaphors.
I'd make it a flyout from the side or bottom of your app that shoves other things out of the way. If it's on top of other stuff that the user might need to see or interact with then it's just gonna annoy them.
I found that showing an an invisible modal dialog on the main UI thread during the blocking stage of the interaction works great.
Hidden modal dialog settings (so it's not visible): ShowInTaskBar=false, FormBorderStyle=None, size={0,0}, Opacity=0%, StartupPosition=CenterParent.
The hidden dialog is shown on the UI thread using ShowDialog. The visible dialog is shown on a separate STA thread. The thread is kicked off before calling hiddenDialog.ShowDialog on the main UI thread.
The visible dialog hides hiddenDialog when it wants the initial blocking state to complete. This stops the main UI thread from blocking.
The important bits of code:
void LaunchWizardForm(s)
{
// Show the wizard on its own thread.
ThreadStart t = () =>
{
_wizard = new WizardForm(s);
Application.Run(new ApplicationContext(_wizard));
};
var thread = new Thread(t);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
// Block this (main UI) thread
_hiddenForm.ShowDialog();
}
void EndModalEpisode()
{
_hiddenForm.Invoke((Action) (() => _hiddenForm.Hide()));
}

Resources