statechanging method - c#

It's just a simple noobie question...
I often use something like this(code) to change my GUI, so my question is if there's something more useful than using bool variables?
Thanks!
//Unity3D - C#
public class GuiBehaviour : MonoBehaviour
{
private bool lookInside = false;
void OnGUI ()
{
if (!lookInside) {
if (GUILayout.Button ("Look Inside")) {
lookInside = true;
}
} else {
if (GUILayout.Button ("Exit View")) {
lookInside = false;
}
}
}
}

what about:
lookInside =!lookInside;
if(lookInside)
{
GUILayout.Button ("Look Inside")
}
else
{
GUILayout.Button ("Exit View")
}

Use different handlers for different buttons, assumes buttons are only visible in either view.
private void InitializeComponent()
{
lookInsideButton = new System.Windows.Forms.Button();
lookInsideButton.Click += new EventHandler(lookInsideButton_Click);
exitViewButton = new System.Windows.Forms.Button();
exitViewButton.Click += new EventHandler(exitViewButton_Click);
}
void lookInsideButton_Click(object sender, EventArgs e)
{
ShowInsideView();
}
void exitViewButton_Click(object sender, EventArgs e)
{
ExitInsideView();
}
System.Windows.Forms.Button lookInsideButton, exitViewButton;

I use enum for better readability and to have more than 2 states. For example:
public class GuiBehaviour : MonoBehaviour
{
private GUIState CurrentState;
enum GUIState
{
LookInside,
ExitView,
GameOverView
}
void OnGUI(GUIState state)
{
CurrentState = state;
switch(state)
{
case GUIState.LookInside:
GUILayout.Button("Look Inside");
break;
case GUIState.ExitView:
GUILayout.Button("Exit View");
break;
case GUIState.LookInside:
GUILayout.Button("Game over");
break;
}
}
}

Related

C# bool and turn on off function with neat way?

I got following code.
public class MpChange : CusEffect
{
bool AlreadyDo = false;
bool AlreadyStop = false;
public override void CondDel(object sender, CondEventArgs e)
{
if (e.CondMet && !AlreadyDo)
{
DoEffect();
AlreadyDo = true;
AlreadyStop = false;
}
else if (!e.CondMet && !AlreadyStop)
{
StopEffect();
AlreadyStop = true;
AlreadyDo = false;
}
}
public override void DoEffect()
{
Debug.Log(WhoEffect.name + "'s Mp changed +5");
}
public override void StopEffect()
{
Debug.Log(WhoEffect.name + "'s Mp changed -5");
}
}
This is called when character's hp is full, (then DoEffect()), and if not full, then StopEffect().
When character's hp is changed, event published and this MpChange class is subscribe it.
In this case, can this code be neat?
I hate to using this 2 boolean variables (AlreadyDo, AlreadyStop), being confused.
One boolean will do:
bool State = false;
public override void CondDel(object sender, CondEventArgs e)
{
if (e.CondMet == State) return; // nothing to do, state's the current one
State = !State; // flip the flag
if (State) { // do or undo a thing
DoEffect();
} else {
StopEffect();
}
}
So instead using boolean, I should use enum.
I set,
public enum ConditionState
{
None, Complete, Incomplete,
}
and change condition code part based on enum state and prevent duplicate calling,
public abstract class CusCondition
{
public bool Earned;
public int SealValueCond;
public ConditionState conditionMet;
private ConditionState prevCond = ConditionState.None;
[HideInInspector]
public Character WhoCondition;
public virtual void ConditionEvent(object sender, MyEventArgs myEventArgs)
{
SealManager.Instance.PublishEvent(this, new CondEventArgs(conditionMet));
}
public virtual void ConditionEventState(object sender, MyEventArgs myEventArgs)
{ // execute only once state changes
if (conditionMet == prevCond) return;
prevCond = conditionMet;
SealManager.Instance.PublishEvent(this, new CondEventArgs(conditionMet));
}
}
and then at effect part, this is enough.
public override void CondDel(object sender, CondEventArgs e)
{
if (e.CondMet == ConditionState.Complete)
DoEffect();
else if(e.CondMet == ConditionState.Incomplete)
StopEffect();
}

Wait for input from a textbox, similar to Console.Read()

So I'm trying to have the user enter some input which derives its data from a class variable. The user will enter their input though a textbox and hit return when finished, causing the event to update the class variable. However, my issue is figuring out how to send a signal from the EventHandler to continue the process. I know a simple solution would be to put the code triggered inside the event method, but I want to use multiple methods with this textbox and input.
Here's what my code currently looks like:
public partial class Form1 : Form
{
private String input;
public Form1()
{
InitializeComponent();
outbox.AppendText("Hello World!"); //outbox is the display
start();
}
private void inbox_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)13)
{
input = inbox.Text; //inbox is the textbox for input;
}
else
{
//do nothing
}
}
private void start()
{
outbox.AppendText("Enter one, two, three or four.");
//---
//this is where the issue arises
//---
if (text_input.Equals("one"))
{
outbox.AppendText("Sunflowers");
}
else if (text_input.Equals("two))
{
outbox.AppendText("Tulips");
}
else if (text_input.Equals("three"))
{
outbox.AppendText("Daisies");
}
else if (text_input.Equals("four"))
{
outbox.AppendText("Poppies");
}
else if (text_input.Equals("quit"))
{
Application.Exit();
}
else
{
outbox.AppendText("Try again.");
start();
}
}
}
What can I do to pause the program until the user hits return and passes a string to input?
You should probably separate the actions before user input from actions that should happen after user input.
If you want to implement different behaviours then it may help to store the program state, including the action you want to perform after user input is complete.
Try something like this, and adapt as required:
public partial class Form1 : Form
{
private String input;
private enum InputMode {
None,
Numbers
}
private class ModeDefinition{
public InputMode Mode {get; private set; }
public string Prompt{get; private set; }
public Action ActionMethod{get; private set; }
public ModeDefinition(InputMode mode, string prompt, Action actionMethod)
{
this.Mode = mode;
this.Prompt = prompt;
this.ActionMethod = actionMethod;
}
}
private InputMode currentMode;
private Dictionary<InputMode,ModeDefinition> modeDefinitions;
public Form1()
{
InitializeComponent();
outbox.AppendText("Hello World!"); //outbox is the display
initialise();
currentMode = InputMode.Numbers;
commenceAction(modeDefinitions[currentMode]);
}
private void initialise(){
modeDefinitions = new Dictionary<InputMode,ModeDefinition>();
var def1 = new ModeDefinition(InputMode.Numbers, "Enter one, two, three or four.", numbersAction);
modeDefinitions.Add(InputMode.Numbers, def1);
}
private void commenceAction(ModeDefinition modeDefinition){
outbox.AppendText(modeDefinition.Prompt);
}
private void inbox_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)13)
{
input = inbox.Text; //inbox is the textbox for input;
var currentMode = modeDefinitions[currentMode];
// Execute the mode action
currentMode.ActionMethod();
}
else
{
//do nothing
}
}
private void numbersAction(){
if (text_input.Equals("one"))
{
outbox.AppendText("Sunflowers");
}
else if (text_input.Equals("two))
{
outbox.AppendText("Tulips");
}
else if (text_input.Equals("three"))
{
outbox.AppendText("Daisies");
}
else if (text_input.Equals("four"))
{
outbox.AppendText("Poppies");
}
else if (text_input.Equals("quit"))
{
Application.Exit();
}
else
{
outbox.AppendText("Try again.");
var currentMode = modeDefinitions[currentMode];
outbox.AppendText(modeDefinition.Prompt);
}
}
}
Don't know my solution is what y need
Firstly , u declare property like this
private string _content;
private string content
{
set
{
if (value != _content)
{
_content = value;
checkContent();
}
}
get
{
return _content;
}
}
private void checkContent()
{
if (content.Equals("one"))
{
outbox.AppendText("Sunflowers");
}
else if (content.Equals("two"))
{
outbox.AppendText("Tulips");
}
else if (content.Equals("three"))
{
outbox.AppendText("Daisies");
}
else if (content.Equals("four"))
{
outbox.AppendText("Poppies");
}
else if (content.Equals("quit"))
{
Application.Exit();
}
else
{
outbox.AppendText("Try again.");
start();
}
}
private void start()
{
outbox.AppendText("Enter one, two, three or four.");
}
private void inbox_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)13)
{
content = inbox.Text; //inbox is the textbox for input;
}
else
{
//do nothing
}
}
}

System.Device.Location.GeoCoordinateWatcher.Position.Location.Speed always is NaN

I'm making a simple app for my WP8.1 device, which will be track my maximum speed. I'm using System.Device.Location.GeoCoordinateWatcher for this. I can detect my position, but speed always is NaN. And I don't understand, why. What is wrong? Thanks for any help or info. It is my full code below:
namespace SpeedTracker
{
public partial class MainPage : PhoneApplicationPage
{
GeoCoordinateWatcher watcher;
double maxSpeed = 0.0;
public MainPage()
{
InitializeComponent();
}
private void StartTrackingBtn_Click(object sender, RoutedEventArgs e)
{
this.watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
this.watcher.MovementThreshold = 10;
this.watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
this.watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
this.watcher.Start();
}
private void StopTrackingBtn_Click(object sender, RoutedEventArgs e)
{
this.watcher.StatusChanged -= new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
this.watcher.PositionChanged -= new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
this.watcher.Stop();
}
private void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
if (this.watcher.Position.Location.IsUnknown != true)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
this.maxSpeed = Math.Max(this.maxSpeed, e.Position.Location.Speed);
this.SpeedValueTxblck.Text = this.maxSpeed.ToString();
});
}
else
{
this.SpeedValueTxblck.Text = "Please wait while your prosition is determined...";
}
}
private void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
switch (e.Status)
{
case GeoPositionStatus.Disabled:
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
this.SpeedValueTxblck.Text = "Location Service is not enabled on the device";
});
break;
case GeoPositionStatus.NoData:
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
this.SpeedValueTxblck.Text = "The Location Service is working, but it cannot get location data";
});
break;
default:
break;
}
}
private void GetLocationCourseAndSpeed()
{
this.watcher.TryStart(true, TimeSpan.FromMilliseconds(1000));
if (watcher.Position.Location.IsUnknown != true)
{
GeoCoordinate coord = watcher.Position.Location;
this.maxSpeed = Math.Max(this.maxSpeed, coord.Speed);
this.SpeedValueTxblck.Text = this.maxSpeed.ToString();
}
else
{
this.SpeedValueTxblck.Text = "Unknown";
}
}
}
}
I don't believe that there is an issue with your code. I am doing a similar function on a device that has WiFi, Cellular and GPS installed. It appears that cellular is the fastest to lock in and does not ever provide any speed data. However, when I disable cell and WiFi, I get speed data from the GPS sensor just fine. If you have dedicated GPS, I would try doing the same thing. If not, you may need it to get what you are looking for.

Access from my main form class into specific class method

This is my main form class and inside i have Stop button click event:
public partial class MainWin : Form
{
private Job job = new...
private void btnStop_Click(object sender, EventArgs e)
{
job.state = true;
}
}
When my stop button clicked i change my job class member from false to true and what i want to do is when this variable changed to true i want to access to specific method inside job class and do something.
public class Job
{
public bool state { get; set; }
private void processFile() // i want access to this method in order to change other class state
{
// do work
}
}
how can i do it ?
It's really hard to tell what you exactly mean, but one way to invoke a method when the property is set would be to expand the auto property out and do exactly that.
public class Job
{
private bool state;
public bool State
{
get { return this.state; }
set
{
this.state = value;
processFile();
}
private void processFile()
{
// do work
}
}
However, just guessing and seeing this little bit of code, you might want to redesign how you're doing things.
If really don't want to expose you private method, you can do something like this:
public class Job
{
private bool state;
public bool State
{
get
{
return state;
}
set
{
if (state != value)
{
state = value;
OnStateChanged();
}
}
}
private void OnStateChanged()
{
if (state) // or you could use enum for state
Run();
else
Stop();
}
private void Run()
{
// run
}
private void Stop()
{
// stop
}
}
But you should really consider creating public Job.Run method and leaving Job.State readonly. If you want the object to perform some operations, the methods will be more suitable for this.
Create the Job class like this:
public class Job
{
private bool _isRunning = false;
public bool IsRunning { get { return _isRunning; } }
public void StartProcessing()
{
if (_isRunning)
{
// TODO: warn?
return;
}
ProcessFile();
}
public void StopProcessing()
{
if (!_isRunning)
{
// TODO: warn?
return;
}
// TODO: stop processing
}
private void ProcessFile()
{
_isRunning = true;
// do your thing
_isRunning = false;
}
}
Then consume it like this:
public partial class MainWin : For
{
private Job _job = new Job();
private void StartButton_Click(object sender, EventArgs e)
{
if(!_job.IsRunning)
{
_job.StartProcessing();
}
}
private void StopButton_Click(object sender, EventArgs e)
{
if(_job.IsRunning)
{
_job.StopProcessing();
}
}
}
Thread safety left out as exercise.

C# Sql Server "loading window"

This is my first post here, but I've using this site regularly to help me with my own app's, and I should say that this site has been a great help to me, so thanks to everyone.
Now my question:
I'm developing my first software app that exchanges data between a sql server and the app itself. It's beeing developed in C#. Saving or retreiving data from the sql server database is no problem.
What I want is a way to inform the user of the delay between the local machine (where the app is installed) and the server. I can make some animations or simply display some text messages. What I need help with is how to create the code that activates/fires/runs when that server communication time is running.
If you can't understand the idea, picture a video game. When it's loading (in some games) you can see the loading screen before the game starts. I need some code that displays that "loading window" when the the app is downloading or uploading data from/to the server.
I would appreciate any code example or web site recommendation.
PS: Sorry for the extensive text, but I want to make sure everyone understand so I don't have to repeat it again :P
How do I implement a progress bar in C#?
How to create a smooth progress bar in Visual C#
ProgressBar Class
I have developed a simple PleaseWait class 2 years ago, but I didn't update this class, It works very well, have look hope this will give you an idea to implement your logic.
public partial class frmWait : Form
{
public frmWait()
{
InitializeComponent();
}
bool _isMoving = false;
int _moveStart_x = 0;
int _moveStart_y = 0;
private void tmrProgress_Tick(object sender, EventArgs e)
{
if (barProgress.Value == barProgress.Maximum)
barProgress.Value = barProgress.Minimum;
else
barProgress.Value += 1;
}
private void btnCancel_Click(object sender, EventArgs e)
{
Close();
PleaseWait.Abort();
}
protected override CreateParams CreateParams
{
get
{
System.Windows.Forms.CreateParams p = base.CreateParams;
p.ClassStyle += 0x20000;
p.ExStyle += 0x8000000;
return p;
}
}
protected override void WndProc(ref Message m)
{
const int WM_NCHITTEST = 132;
base.WndProc(ref m);
switch (m.Msg)
{
case WM_NCHITTEST:
if (m.Result.ToInt32() == 1)
m.Result = new IntPtr(2);
break;
}
}
private void panelEx1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_isMoving = true;
_moveStart_x = e.X;
_moveStart_y = e.Y;
}
}
private void panelEx1_MouseUp(object sender, MouseEventArgs e)
{
_isMoving = false;
}
private void pnlContainer_MouseMove(object sender, MouseEventArgs e)
{
if (_isMoving)
this.Location = new Point(Location.X + e.X - _moveStart_x, Location.Y + e.Y - _moveStart_y);
}
}
public class PleaseWait
{
#region Static Operations
private static Boolean _isAborted = false;
private static Boolean _isVisible = false;
private static frmWait _waitForm;
private static String _waitingState = "";
private static Boolean _autoClose = false;
private static Boolean _cancelable = false;
private static System.Threading.Thread _waiterThred;
public delegate void CancelButtonPressed();
public static event CancelButtonPressed OnCancel;
public static Boolean AutoClose
{
get { return PleaseWait._autoClose; }
set { PleaseWait._autoClose = value; }
}
public static string WaitingState
{
get { return PleaseWait._waitingState; }
set { PleaseWait._waitingState = value; }
}
public static bool IsVisible
{
get { return _isVisible; }
internal set { _isVisible = value; }
}
public static void ShowPleaseWait()
{
ShowPleaseWait("", _autoClose, false);
}
public static void ShowPleaseWait(string waitingState)
{
ShowPleaseWait(waitingState, _autoClose, false);
}
public static void ShowPleaseWait(bool autoClose)
{
ShowPleaseWait("", autoClose, false);
}
public static void ShowPleaseWait(string waitingState, bool autoClose, bool cancelable)
{
if (_waiterThred != null)
{
if (_isVisible)
{
// the please wait it woking, just continue and apply the changes
_waitingState = waitingState;
_autoClose = autoClose;
_cancelable = cancelable;
return;
}
else
{
_waiterThred.Abort();
_waiterThred = null;
}
}
_waitingState = waitingState;
_autoClose = autoClose;
_cancelable = cancelable;
_isAborted = false;
_isVisible = false;
if (_autoClose)
Application.Idle += new EventHandler(Application_Idle);
_waiterThred = new System.Threading.Thread(DisplayWaitingForm);
_waiterThred.IsBackground = true;
_waiterThred.Name = "Please Wait....";
_waiterThred.Start();
Application.DoEvents();
}
public static void Abort()
{
_isAborted = true;
}
private static void Application_Idle(object sender, EventArgs e)
{
if (_autoClose)
_isAborted = true;
}
private static void DisplayWaitingForm()
{
if (_waitForm != null)
{
if (!_waitForm.IsDisposed)
_waitForm.Dispose();
_waitForm = null;
_isVisible = false;
}
try
{
if (_isAborted)
return;
_waitForm = new frmWait();
if (_cancelable)
{
_waitForm.btnCancel.Enabled = true;
_waitForm.btnCancel.Click += new EventHandler(btnCancel_Click);
}
try
{
_isVisible = true;
_waitForm.Show();
_waitForm.Focus();
while (!_isAborted)
{
System.Threading.Thread.Sleep(15);
_waitForm.lblMessage.Text = _waitingState;
Application.DoEvents();
_waitForm.lblMessage.Text = _waitingState;
}
_isVisible = false;
}
finally
{
FreeWaitingForm();
}
}
finally
{
_isVisible = false;
}
}
static void btnCancel_Click(object sender, EventArgs e)
{
if (_waitForm.InvokeRequired)
{
_waitForm.BeginInvoke(new EventHandler(btnCancel_Click), new object[] { e });
}
else
{
if (OnCancel != null)
OnCancel.Invoke();
}
}
private static void FreeWaitingForm()
{
_waitingState = "";
_isVisible = false;
if (_waitForm == null)
{
return;
}
_waitForm.Hide();
if (!_waitForm.IsDisposed)
_waitForm.Dispose();
_waitForm = null;
}
#endregion
}
use like following code :
PleaseWait.ShowPleaseWait("Please wait", true, false);
// If second param is true then it will close the form automatically.
// If third param is true the it will expose a cancel button, so you can cancel your Asynchronous operations.
I didn't insert design code, you can understand by looking at code.
hope this help.
First let me thank you for your replies.
Toby your answer got me thinking about thread monitoring my sql connections but it was a bit tricky and confusing since the app is still in develop and will use a lot more connections.
S.Amani answer it wasn't quite what I want, but thanks to that I found a easier way. I created a form (could be anything else), placed a label saying: Saving To Data Base, took out the top bar, defined location and defined it's parent to be disabled when shown and enabled when closed. The following code is what I put inside my DataBaseInteractionClass
private Wait myCustomWaitDialog = new Wait(); // My Waiting form
private void SaveToDatabase(myObjectToSave obj) // Method called to save data do DB
{
// Create the connections and queries
(...)
// This is what I did
// Show Waiting Form
myCustomWaitDialog.Show();
// Instanciate the command that will carry the query and to DB
SqlCommand command = new SqlCommand(Queries.GetData(code), conn);
// This is important
//Create event that will fire when the command completes
command.StatementCompleted += new StatementCompletedEventHandler(command_StatementCompleted);
// Execute the transaction
SqlDataReader reader = command.ExecuteReader();
// Rest of the code (validations, close connections, try/catch, etc
(...)
}
void command_StatementCompleted(object sender, StatementCompletedEventArgs e)
{
// This is the method that closes my Waiting Dialog
myCustomWaitDialog.CloseDialog();
myCustomWaitDialog.Dispose();
}
It's not quite what I want yet, but is the best solution that I found so far. For now it will do :)
Anyway, thanks for the replies and I hope this helps someone else.

Categories