I am running a long process as a background process as the process makes my UI unresponsive.
Now the issue is that, while the process is running as a background process, I want to display a wait cursor. I tried using dispatcher to update the cursor, but it does not work.
My process runs on button click:
private void btnStartAsyncOperation_Click(object sender, EventArgs e)
{
backgroundworkerprocess.RunWorkerAsync();
}
In the backgroundworkerprocess event:
void backgroundworkerprocess_DoWork(object sender, DoWorkEventArgs e)
{
this.dispatcher.invoke(DispatcherPriority.Background,
new action((delegate) {
this.cursor = cursors.wait
})
);
}
I was hoping this would cause a wait cursor to be displayed anywhere on the form, but it's only showing up when the mouse is over the button.
private void btnStartAsyncOperation_Click(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;
backgroundworkerprocess.RunWorkerAsync();
}
void backgroundworkerprocess_DoWork(object sender, DoWorkEventArgs e)
{
// do work
}
Then just simply change the Cursor back in the RunWorkerCompleted event.
I dont think people understand you.
try this, sending it to Dispatcher:
Window.GetWindow(this).Cursor = Cursors.WaitCursor;
Related
I tried with background worker. When function with loading database data is called, i call backgroundworker too, and i want to open another form which will have progress bar and when loading data is finished, i want to close that form and let user use app normaly. I tried this
private void SearchBtn_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
//loading data
}
this is function which takes long time to execute so i call background worker.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
f.Show();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
f.Close();
}
f is my form global varibale , when i write like this, i get error that i cant close form which has been opened in another thread. So what im doing wrong.
You must Invoke the method on the thread that owns the control:
Invoke(new Action(() => f.Close()));
Take a look at Invoke method.
I want to show "Loading.., please wait" gif by getting content from web.
I have tried the following code, but Picturebox opening too late.
private void buttonStart_Click(object sender, EventArgs e)
{
pictureBox1.Visible = true;
webSatList = new WebSatelliteList(this, XMLSatList, name);
webSatList.LoadTPList();
TPListToBeAdded = webSatList.GetTPListToBeAdded();
TPListToBeRemoved = webSatList.GetTPListToBeRemoved();
drawTPListGridView(TPListToBeAdded, TPListToBeRemoved);
}
public void drawTPListGridView(List<TPInfo> TPListToBeAdded, List<TPInfo> TPListToBeRemoved)
{
pictureBox1.Visible = false;
//draw TP List ..
}
Picturebox is openning after this line:
"TPListToBeRemoved = webSatList.GetTPListToBeRemoved();"
I have tried to fix this problem by using backgroundworker (the following code) and the same problem has been seen. Also, I have used the popup form instead of PictureBox nothing has changed.
private void buttonStart_Click(object sender, EventArgs e)
{
pictureBox1.Visible = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
webSatList = new WebSatelliteList(this, XMLSatList, name);
webSatList.LoadTPList();
TPListToBeAdded = webSatList.GetTPListToBeAdded();
TPListToBeRemoved = webSatList.GetTPListToBeRemoved();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
drawTPListGridView(TPListToBeAdded, TPListToBeRemoved);
}
public void drawTPListGridView(List<TPInfo> TPListToBeAdded, List<TPInfo> TPListToBeRemoved)
{
pictureBox1.Visible = false;
//draw TP List ..
}
How can i fix this problem? Any help would be appreciated.
Not entirely sure what you're trying to do here, but chances are you want to implement the async / await pattern.
Mark your button press as async
private async void buttonStart_Click(object sender, EventArgs e)
For anything that you need to wait for should then be awaited and it will keep your form redrawing so it doesn't freeze up. For example, something like:
await Task.Run(() => loadPictureBox());
Or you could make your loadpicturebox method asynchronous by giving it a signature of async Task.
The problem you're likely having is that the form will not update or refresh itself until the click method has exited. This means if you first make it display a loading image, and then load the next image in the same method that the form will freeze up until both operations have finished and the method has exited.
The async await pattern means that while it's doing some processing or whatever, let windows carry on drawing the form and handling actions on it.
okay so what I want to do, it when the mouse is HELD DOWN I want it to continously press a key. it should continously press this key until I let off.
Imagine if you will, a left and right button on a windows form,
then by clicking and holding the right button, the letter "R" displays on a textbox continously until you release the button. What I am doing has very little to do with that scenario, but you get what I'm trying to do here.
What exactly do I put in the mouse down to keep the sendkeys going forever without locking up the application?
I hope my question makes sense. lol.
Thanks
RT
private void pictureBoxKeyboard_MouseDown(object sender, MouseEventArgs e)
{
//something goes here
}
This is worth a read...
http://msdn.microsoft.com/en-us/library/ms171548.aspx
SendKeys.Send("r")
This might just fire once, you may want to attach a timer that starts on the MouseDown event and stops on the MouseUp event. Then you could put the SendKeys in the Timer.Tick event.
private void Form1_Load(object sender, EventArgs e)
{
this.timer1.Interval = 500;
}
private void button1_MouseUp(object sender, MouseEventArgs e)
{
timer1.Stop();
this.Text = "moose-Up";
}
private void button1_MouseDown(object sender, EventArgs e)
{
timer1.Start();
this.Text = "moose-Down";
this.richTextBox1.Select();
}
private void timer1_Tick(object sender, EventArgs e)
{
SendKeys.Send("r");
Debug.Print("tickling");
}
Select the control that you wish to receive the SendKeys value...
I am working on a WPF application where i handled a mouse down event which eventually shows up
MessageBox.. But after MessageBox appears on mouseDown, it eats up corresponding MouseUp event of a control.
Scenario can be easily reproduced by simply handling MouseDown and MouseUP event in WPF window
as:-
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
MessageBox.show("Hello, Mouse down");
}
private void Window_MouseUP(object sender, MouseButtonEventArgs e)
{
MessageBox.show("Hello, Mouse Up");
}
MouseUp message is never shown, once messagebox appears on MouseDown event.
What about initializing a new instance of System.Threading.Thread to call the MessageBox so that the main user interface thread would not be interrupted by the prompt?
Example
private void Window_MouseDown(object sender, MouseEventArgs e)
{
Thread mythread = new Thread(() => MessageBox.Show("Hello, Mouse Down")); //Initialize a new Thread to show our MessageBox within
mythread.Start(); //Start the thread
}
private void Window_MouseUP(object sender, MouseEventArgs e)
{
Thread mythread = new Thread(() => MessageBox.Show("Hello, Mouse Up")); //Initialize a new Thread to show our MessageBox within
mythread.Start(); //Start the thread
}
Screenshot
Thanks,
I hope you find this helpful :)
As the commenter on your original post said, it seems that what's happening here is that the user's mouse wanders out of focus to click in the message box, or even just to display it, so the mouse moves "up" anyway - the event is never called.
If you're just wanting to display messageboxes, then simply using:
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
MessageBox.show("Hello, Mouse down");
MessageBox.show("Hello, your mouse must be up because you've shifted focus!");
}
should do the job. If this behaviour repeats for something like changing a window title, or anything that doesn't require user input, then this could be a problem, but I am 100% sure that this is just an issue with regards to the MessageBox. Hope this helped.
#picrofo solution is also good and easy but i did by this way
DialogResult result;
private void button1_MouseDown(object sender, MouseEventArgs e)
{
string message = "would you like to see mouse up event?";
string caption = "event trick";
MessageBoxButtons buttons = MessageBoxButtons.YesNo;
result = MessageBox.Show(message, caption, buttons);
textBox1.Text = result.ToString();
if (result == System.Windows.Forms.DialogResult.Yes)
{
button1_MouseUp(sender, e);
}
}
I have a strange bug, please, let me know if you have any clues about the reason.
I have a Timer (System.Windows.Forms.Timer) on my main form, which fires some updates, which also eventually update the main form UI. Then I have an editor, which is opened from the main form using the ShowDialog() method. On this editor I have a PropertyGrid (System.Windows.Forms.PropertyGrid).
I am unable to reproduce it everytime, but pretty often, when I use dropdowns on that property grid in editor it gets stuck, that is OK/Cancel buttons don't close the form, property grid becomes not usable, Close button in the form header doesn't work.
There are no exceptions in the background, and if I break the process I see that the app is doing some calculations related to the updates I mentioned in the beginning.
What can you recommend? Any ideas are welcome.
What's happening is that the thread timer's Tick method doesn't execute on a different thread, so it's locking everything else until it's done. I made a test winforms app that had a timer and 2 buttons on it whose events did this:
private void timer1_Tick(object sender, EventArgs e)
{
Thread.Sleep(6000);
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void button2_Click(object sender, EventArgs e)
{
frmShow show = new frmShow();
show.ShowDialog(); // frmShow just has some controls on it to fiddle with
}
and indeed it blocked as you described. The following solved it:
private void timer1_Tick(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(DoStuff);
}
private void DoStuff(object something)
{
Thread.Sleep(6000);
}