Wait for variable to change - c#

I have a method that shows a window and then returns the value of the button clicked. What I have done is that when I click the button I change a variable and then the variable will be returned. What I need is someway to pause the method until the variable has been changed.
I program a game in unity and it's using mono.
Code:
public virtual Buttons Execute(){
this.holder.SetActive(true); //Set the window active
// Here wait for the user to click a button
return clicked;//Returns the button clicked.
}

The code that handles the user interface is event driven, so the sensible thing to do would be to use an event instead of using a method like you try to do.
It's possible to create a method that works that way, but you have to create your own message pump that runs while you are waiting:
public virtual Buttons Execute(){
this.holder.SetActive(true); // Set the window active
clicked = null; // Set the state as undetermined
while (clicked == null) { // Wait until it is set
Application.DoEvents(); // Process messages
Thread.Sleep(10); // Wait for a while
}
return clicked; // Returns the button clicked.
}
You can read in the question Use of Application.DoEvents() for explanations of the pitfalls of using DoEvents this way.

Related

What's the difference between actually click a button and the InvokeOnClick() method?

I wanna change a widget's backcolor at a appropriate point with the statement below:
IpAddressTextEdit.BackColor = Color.LimeGreen;
After trying many approaches, it finally works when I put this into a button_click event method and actually click the button physically. Just like below:
public void button3_Click(object sender, EventArgs e)
{
IpAddressTextEdit.BackColor = Color.LimeGreen;
Console.WriteLine("Button 3 is clicked ! ");
}
But, I never want to do this via a click and it doesnt work when I invoke this click by using InvokeOnClick() at somewhere else. Even my debugger indicates that this statement has been executed, and the assignment is successful, the "Button 3 is clicked !" is also printed, all is going as same as actual click. The only difference is my widget doesnt change its color.
I can guess there're some mechanisms behind and debugger wont show me. This assignment just stay background and never impact the front UI. So what is the real difference btw InvokeOnClick and actual click. What should I do to make it work.
code of InvokeOnClick():
if (TcpSocket.Connected)
{
MainForm mf = new MainForm();
SettingsControl sc = new SettingsControl();
sc.IpAddressTextEdit.BackColor = Color.LimeGreen; // assign directly
mf.InvokeOnClick(sc.button3, EventArgs.Empty); // Invoke a btn click
sc.OnSocketConnectedEventHandler(EventArgs.Empty); // raise a event create by my own
if(!SocketRecvThread.IsAlive)
SocketRecvThread.Start(); //Begin receive;
mf.SetupLeakDetector(); //Send command to setup machine
}
As can be seen, I've try approaches including assign the color directly, invoke a event that create by my own, invoke a btnclick event. None of them work.
As you describe the behaviour the only difference I can see is the timinig. So what is the difference between setting backgroundcolor before or after the form is shown? Well you got some events to inspect, Like Form_Load, Form_Shown or Form_Activate. If the backgroundcolor of your textbox is set in any of these events (or in methods called in these events) it will overwrite what you have set before calling .Show() / .ShowDialog() on your form
Complete list of events when a form is shown

Windows Phone Back KeyPress + MessageBox crashes the app without Selection

I have a strange issue overriding BackkeyPress Function in code behind, inside the function i have a simple message box to Go back or cancel navigation ( stay in current page ), when no choice is made (ok or cancel ) and Messagebox is open for long time, Application crashes, when i try to debug, no exception is thrown and App remains in the state unless OK or cancel is pressed , but on Normal run ( without debugger ) the crash is apparent.
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
string caption = "exit?";
string message = "Do you still want to exit?";
e.Cancel = MessageBoxResult.Cancel == MessageBox.Show(message, caption,
MessageBoxButton.OKCancel);
base.OnBackKeyPress(e);
}
http://msdn.microsoft.com/en-US/library/windowsphone/develop/jj206947(v=vs.105).aspx
In Windows Phone 8, if you call Show in
OnBackKeyPress(CancelEventArgs) or a handler for the BackKeyPress
event, the app will exit.
You can work around this by calling Show on a different thread, as
described in the following steps. Override BackKeyPress or create a
handler for the BackKeyPress event. Set the Cancel to true to cancel
the back key press action. Dispatch a method that shows the
MessageBox. If the user chooses to leave the app, call Terminate(),
otherwise, do nothing.
I found one more solution to this, so I thought it would be good if I posted it here. It's just a workaround though.
private async void PhoneApplicationPage_BackKeyPress (object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
await Task.Delay(100);
if (MessageBox.Show(msg, cap, MessageBoxButton.OKCancel) == MssageBoxResult.OK)
{
//somecode
}
}
Source
When using Terminate() - be aware that a number of app.xaml.cs rootFrame navigating events associated with normal exit won't trigger, neither the ApplicationClosing or your page's OnNavigatedFrom. So check if anything going on is important. You might tack it on before terminating...

Disabling all execution for a period of time

I need to disable all execution of any event (click) for a period of time after l click a button. At that particular period, no matter how many buttons I click the functions of buttons will not be executed. I cannot use the Thread.Sleep() because it only delays the execution, the function of the button still being executed. Does any1 can help? My code is here:
int delay = 2000; //unusable as it is just delaying the execution of clicked button.
public void PressCOM(string key)
{
if (key == "PressSc")
{
PressAndRelease(key);
PressAndRelease("C");
Thread.Sleep(delay);
}
Sleeping on the main thread is a bad idea anyway.
You will have to built in some logic concerning the buttons to either:
disable them
ignore clicks
Use a Boolean property that is reset by a timer.
Disabling and showing a "Please Wait..." kind of message to the user will be a better option...
You can Disable and enable the panels .Grids in WPF as you like
I Usually use a Adorner Overlay (translucent) with a message to stop user from interacting with the UI... usually Backround worker helps to Show and Hide the overlay when required.
This will be a Good Artice for Adorner implemtation in XAml
hope it helps.. :)
It's not really clear what you want to do.
It's not a really good idea to put a sleep in the main application thread. It will make your application unresponsive to all Windows messages (both originated by user or by Windows itself). Your users will fill it hanged.
If you need to disable only that button you may set its IsEnabled property to false, user won't be able to click it.
If you want to disable all events you can use the IsEnabled property of the window itself.
If to disable all controls (or just one button) isn't the right solution for you then you may use one of the followings.
Add a state variable (or a simple flag). In all your event handlers you'll check if that variable is true or not (you'll change it with a timer). Something like:
if (!_canHandleMouseClicks)
return false;
Disable all buttons and re-enable them after a period of time:
private static IEnumerable<Button> FindAllButtons(DependencyObject obj)
{
if (obj == null)
return null;
int childrenCount = VisualTreeHelper.GetChildrenCount(obj);
for (int i = 0; i < childrenCount; ++i)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is Button)
yield return (Button)child;
// If you may have buttons inside buttons then uncomment these lines
//foreach (Button childOfChild in FindAllButtons(child))
// yield return childOfChild;
}
}
Then you can write:
foreach (Button button in FindAllButtons(window))
button.IsEnabled = false; // true to re-enable
A possible solution might be to show a dialog and hide the dialogs ok, cancel and close buttons. This will prevent any button from being clicked in the main-window.

Execute method On-Load of an object on a form in C#

E.g. instead of having a button to initiate the method, the method automatically happens without any user interaction - automatically.
private void button13_Click(object sender, EventArgs e)
{
try
{
ServiceController sc = new ServiceController();
sc.ServiceName = "Spooler";
if (sc.Status.ToString().ToLower() == "stopped")
{
serviceStatusLabel.Text = "Installed but stopped";
}
if (sc.Status.ToString().ToLower() == "running")
{
serviceStatusLabel.Text = "Installed and started";
}
}
catch
{
serviceStatusLabel.Text = "Service not installed";
}
}
I just want the Label object to show the service status when the form is loaded up, without using a button
EDIT: Given your comment, are you actually after the Form.Load event? It sounds like it. Any event handlers subscribed to that event will be executed "when the form is displayed for the first time".
(The confusing thing is that your title talks about "On-Load" of an object whereas it sounds like you really want the method to be called when the form is loaded.)
It's not really clear what you mean by "when its output on the form" but you might want to look at the TextChanged and VisibleChanged events. That's if you want something to happen when the label is altered.
If you're looking for when the service status is altered, it doesn't look like there's an event raised for that, I'm afraid. Note that it would be much cleaner to switch on the enum value rather than to convert it to a string, lower it, and then compare that with hard-coded constants.
... Do I get your question correctly?
You want a piece of code to be executed when an object or the form is loaded?
Well that's easy :p
Click on your object (or form) in the designer, in the properties dock, click the lightning bolt icon, go to the Load or Show event, and double-click the box.
A new piece of code should now be created in the code view, something like this:
private void Object_Load(blabla) handles Object.Load
{
}
Whatever code is in that event will be executed when the object is loaded or shown.
If you create a handler for the Load event, it will run when the form gets loaded.

Handling the "X" close button in WPF under MVVM

I'm creating a basic database application in WPF, and I have started using the MVVM pattern.
I have a dialog that asks the user to select an item from a ListBox and click "OK." After that, I take the item the user clicked from a property in the view model and pass it into another dialog. But if the user clicks "Cancel," I set that value to null, and the action is canceled: I don't open the next dialog and return to the main screen. Example:
public class SelectEquipmentViewModel : WorkspaceViewModel
{
private bool _selected;
public Equipment SelectedEquipment
{
// Item selected by the user
}
// Action for "SelectCommand," which is attached to
// the "Select" button in the view
public void ExecuteSelect()
{
_selected = true;
// Fires a RequestClose event in WorkspaceViewModel,
// which is attached to the view's Close method
RequestClose();
}
public override void RequestClose()
{
if (!_selected)
{
// The user clicked "Cancel"
SelectedEquipment = null;
}
base.RequestClose();
}
}
This has been working great, but the problem comes if the user clicks the red "X" close button in the window's control box. The RequestClose method never gets invoked, and the selected item isn't set to null, which is bad.
I've considered attaching the view model to the Closing event of the view, but I feel this could get messy if I start creating handlers for all these events.
What would be the "preferred" way of handling this situation?
Thanks.
I think that using the EventToCommand behavior to wire up the Window object's Closing event to a new ExecuteCancel command is pretty clean.
public void ExecuteCancel()
{
_selected = false;
// Fires a RequestClose event in WorkspaceViewModel,
// which is attached to the view's Close method
RequestClose();
}
Where do you think this will get messy? If you add a Cancel button, it could use the same ExecuteCancel bits...
Behaviors are what you want to use to execute a command when the user presses the "X" button on window using MVVM. Check out Reed Copsey's blog here: http://reedcopsey.com/2009/10/09/using-behaviors-to-allow-the-viewmodel-to-manage-view-lifetime-in-m-v-vm/
You can download a sample application here...
I use this method all the time to allow the ViewModel manage the life of the view.
Approach without additional dependencies is described in article Handling a Window's Closed and Closing events in the View-Model and code with example provided. This does not add code behind xaml.
(Thanks to Reed Copsey's link)

Categories