Crash when doubleclicking a button containing popModalAsync - c#

When doubleclicking a button that executes the code
await Navigation.PopModalAsync(true);
the program enters break mode i.e. crashes. How should it be handled so it wont crash when spamclicking?
EDIT
I changed the parameter to false and it works as expected. Is there any workaround to keep the animation set on true?
SOLVED
simple solution:
Boolean _istapped = false;
private async void Button_Clicked(object sender, EventArgs e)
{
if (_istapped)
return;
_istapped = true;
await Navigation.PopModalAsync(true);
_istapped = false;
}

The app crash because when you double click the button, Navigation.PopModalAsync will execute twice and it can't find the page at the second time.
Here is another simple way to solve this problem:
private async void Button_Clicked(object sender, EventArgs e)
{
Button btn = sender as Button;
btn.IsEnabled = false;
await Navigation.PopModalAsync(true);
//btn.IsEnabled = true;
}

Related

Button disabling while method execution (PreviewLeftMouseDown/Up must be workable)

I need a sequence as follows:
button default state
button Down, "methods for button Down" execute and Button itself is disabled for a time.
button is enabled since "Disabling" time is elapsed, button Up, "methods for button Up" execute.
button default state
I've tried this code and it acts at its first part properly. But second part (Up) does not execute.
Could anyone help me?
private void btn1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var btn = (Button)sender;
btn.IsEnabled = false; //Disable button.
var fooTimer = new System.Timers.Timer(5000); //Exceute after 5000 milliseconds
fooTimer.Elapsed += (fooTimer_s, fooTimer_e) =>
{
//It has to be dispatched because of thread crossing if you are using WPF.
Dispatcher.Invoke(() =>
{
btn.IsEnabled = true; //Bring button back to life by enabling it.
fooTimer.Dispose();
});
};
fooTimer.Start();
// methods for button Down go here
}
private void btn1_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
// methods for button Up go here
}
thanks in advance!
You could do this more easily in an async Click handler:
private async void Button_Click(object sender, RoutedEventArgs e)
{
var button = (Button)sender;
button.IsEnabled = false;
await Task.Run(() =>
{
// perform time-consuming action
Thread.Sleep(5000); // just for test
});
button.IsEnabled = true;
}

WPF WebBrowser disable clicking & typing

Is there a way to prevent users in clicking and typing in WPF WebBrowser? It appears to me that it is only possible to do this in WinForms.
Things that I've tried:
browser.IsEnabled = false; - didn't work, can still click (navigate) and type in text
browser.Focusable = false; - same
having overlay button, which would consume clicks and focus - WebBrowser is a special element, that is always on top of other elements
having another WebBrowser on top of the main one with blank page loaded and opacity set to 0% as an alternative to overlay button (3.) - WPF WebBrowsers do not properly handle opacity, didn't work
browser_MouseDown event with e.Handled = true; - the event is for some reason not called on mouse down
Is there something that I've missed or did wrong in my attempts?
Three events and Boolean did it for me.
bool BrowserIsLoaded = false;
private void Browser_LoadCompleted(object sender, NavigationEventArgs e)
{
BrowserIsLoaded = true;
}
private void Browser_Navigating(object sender, NavigatingCancelEventArgs e)
{
if(BrowserIsLoaded)
e.Cancel = true;
}
private void Browser_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (BrowserIsLoaded)
e.Handled = true;
}
When the browser has finished loading it triggers the LoadCompleted event. Set a Boolean then check that when trying to navigate to a new page when they try to type in a box.
If you don't want to use your own Boolean (I used it for other things so it made sense to me) you can just ask the browser if it's loaded when ever you need it:
private void Browser_Navigating(object sender, NavigatingCancelEventArgs e)
{
WebBrowser wb = (WebBrowser)sender;
if(wb.IsLoaded)
{
e.Cancel = true;
}
}

C# richBox1 text disable

I have problem with richBox1 text disabling.
I've tryed richTextBox1.readonly = true; and richTextBox1.Enabled = false;
My code:
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
richTextBox1.ReadOnly = !richTextBox1.ReadOnly;
}
Its disabling after one letter.
EDIT: And if disable I can still copy text but cant write there.
Honestly, disabling expected functionality is not something you should be doing. It is not good UI design.
The event TextChanged is fired every time the text changes (including writing or removing one letter). You can use Form's Load event (by double clicking the form on design time) :
private void Form1_Load(object sender, EventArgs e)
{
richTextBox1.ReadOnly = true;
richTextBox1.Enabled = false;
}

picturebox opening too late

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.

How would I make a cancel button work like the "X" button?

In my XAML file, I have a window and I am trying to make it so the behavior is the same whether the user clicks the "X" button, or if he clicks the "Cancel" button.
My abridged code is below:
public partial class Dialog : Window
{
.
.
.
private void Window_Closing(object sender, CancelEventArgs e)
{
e.Cancel() = true; //Works as expected
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
e.Cancel() = true; //Compile error
}
}
So I realize that my problem is that RoutedEventArgs does not have a Cancel() method. Does anyone know how I can make RoutedEventArgs work more like CancelEventArgs?
Set the IsCancel property of the button to True.

Categories