The SelectedIndexChanged event gets fired in my application from a combo box when:
the user chooses a different
item in the combo box, or when:
my own code updates the combo
box's SelectedItem to reflect that
the combo box is now displaying
properties for a different object.
I am interested in the SelectedIndexChanged event for case 1, so that I can update the current object's properties. But in case 2, I do not want the event to fire, because the object's properties have not changed.
An example may help. Let's consider that I have a list box containing a list of people and I have a combo box representing the nationality of the currently selected person in the list. Case 1 could happen if Fred is currently selected in the list, and I use the combo box to change his nationality from English to Welsh. Case 2 could happen if I then select Bob, who is Scottish, in the list. Here, my list update event-handler code sees that Bob is now selected, and updates the combo box so that Scottish is now the selected item. This causes the combo box's SelectedIndexChanged event to be fired to set Bob's nationality to Scottish, even though it already is Scottish.
How can I update my combo box's SelectedItem property without causing the SelectedIndexChanged event to fire? One way would be to unregister the event handler, set SelectedItem, then re-register the event handler, but this seems tedious and error prone. There must be a better way.
I created a class I called SuspendLatch. Offers on a better name are welcome, but it does what you need and you would use it like this:
void Method()
{
using (suspendLatch.GetToken())
{
// Update selected index etc
}
}
void listbox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (suspendLatch.HasOutstandingTokens)
{
return;
}
// Do some work
}
It's not pretty, but it does work, and unlike unregistering events or boolean flags, it supports nested operations a bit like TransactionScope. You keep taking tokens from the latch and it's only when the last token is disposed that the HasOutstandingTokens returns false. Nice and safe. Not threadsafe, though...
Here's the code for SuspendLatch:
public class SuspendLatch
{
private IDictionary<Guid, SuspendLatchToken> tokens = new Dictionary<Guid, SuspendLatchToken>();
public SuspendLatchToken GetToken()
{
SuspendLatchToken token = new SuspendLatchToken(this);
tokens.Add(token.Key, token);
return token;
}
public bool HasOutstandingTokens
{
get { return tokens.Count > 0; }
}
public void CancelToken(SuspendLatchToken token)
{
tokens.Remove(token.Key);
}
public class SuspendLatchToken : IDisposable
{
private bool disposed = false;
private Guid key = Guid.NewGuid();
private SuspendLatch parent;
internal SuspendLatchToken(SuspendLatch parent)
{
this.parent = parent;
}
public Guid Key
{
get { return this.key; }
}
public override bool Equals(object obj)
{
SuspendLatchToken other = obj as SuspendLatchToken;
if (other != null)
{
return Key.Equals(other.Key);
}
else
{
return false;
}
}
public override int GetHashCode()
{
return Key.GetHashCode();
}
public override string ToString()
{
return Key.ToString();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Dispose managed resources.
parent.CancelToken(this);
}
// There are no unmanaged resources to release, but
// if we add them, they need to be released here.
}
disposed = true;
// If it is available, make the call to the
// base class's Dispose(Boolean) method
//base.Dispose(disposing);
}
}
}
I think the best way would be to use a flag variable:
bool updatingCheckbox = false;
void updateCheckBox()
{
updatingCheckBox = true;
checkbox.Checked = true;
updatingCheckBox = false;
}
void checkbox_CheckedChanged( object sender, EventArgs e )
{
if (!updatingCheckBox)
PerformActions()
}
[Edit: Posting only the code is not really clear]
In this case, the event handler wouldn't perform its normal operations when the checkbox is changed through updateCheckBox().
I have always used a boolean flag variable to protect against unwanted event handlers. The TaskVision sample application taught me how to do this.
Your event handler code for all of your events will look like this:
private bool lockEvents;
protected void MyEventHandler(object sender, EventArgs e)
{
if (this.lockEvents)
{
return;
}
this.lockEvents = true;
//Handle your event...
this.lockEvents = false;
}
I let the event fire. But, I set a flag before changing the index and flip it back after. In the event handler, I check if the flag is set and exit the handler if it is.
I think your focus should be on the object and not on the event that's occuring.
Say for example you have the event
void combobox_Changed( object sender, EventArgs e )
{
PerformActions()
}
and PerformActions did something to the effect of
void PerformActions()
{
(listBox.SelectedItem as IPerson).Nationality =
(comboBox.SelectedItem as INationality)
}
then inside the Person you would expect to see something to the effect of
class Person: IPerson
{
INationality Nationality
{
get { return m_nationality; }
set
{
if (m_nationality <> value)
{
m_nationality = value;
this.IsDirty = true;
}
}
}
}
the point here is that you let the object keep track of what is happening to itself, not the UI. This also lets you keep track of dirty flag tracking on your objects, which could be useful for persistence later on.
This also keeps your UI clean and keeps it from getting odd event registration code that will most likely be error prone.
I have finally found a solution to avoid the uncessary event from being fired too many time.
I use a counter and I only hook/unhook the events I want to mask once when it is not needed, and when it is needed again.
The example below shows how I hide the CellValueChanged event of a datagrid.
EventMask valueChangedEventMask;
// In the class constructor
valueChangedEventMask = new EventMask(
() => { dgv.CellValueChanged += new DataGridViewCellEventHandler(dgv_CellValueChanged); },
() => { dgv.CellValueChanged -= new DataGridViewCellEventHandler(dgv_CellValueChanged); }
);
// Use push to hide the event and pop to make it available again. The operation can be nested or be used in the event itself.
void changeCellOperation()
{
valueChangedEventMask.Push();
...
cell.Value = myNewCellValue
...
valueChangedEventMask.Pop();
}
// The class
public class EventMask
{
Action hook;
Action unHook;
int count = 0;
public EventMask(Action hook, Action unHook)
{
this.hook = hook;
this.unHook = unHook;
}
public void Push()
{
count++;
if (count == 1)
unHook();
}
public void Pop()
{
count--;
if (count == 0)
hook();
}
}
Related
I have a form, I select some checkboxes, edit some text field, select from a combobox etc. then I click Exit. Based on the fact that "Data has been changed ??" I wish to perform actions. The problem is I can't get the event work :
private void DataChanged(object sender, EventArgs e)
{
MessageBox.Show("Data is changed", "debug");
isDataSaved = false;
}
When is this method called, how do I make it work? Is this supposed to get fired when the form's fields have some data i.e filL a text box ?
I dont really get the API: DataChanged event
Note: I'm following Mike Murach C# 5th edition chapter 10 example.
Edit (exact words from book):
Generate an event handler named DataChanged for the
SelectedIndexChanged event of the XXXX Name combo box. Then , wire
this event handler to the TextChanged event of the YYYYY Method label
and add the code to this event handler so it sets the isDataSaved
variable to false
When I double click on the commbo box the generated event handler it is not named DataChanged but cboNames_SelectedIndexChanged... (is this a book screw up or me total noob ? PS: There is no .. 'database' in the project)
Personally I mostly use databinding these days to get notified of changes in data.
A data holder class, which implements INotifyPropertyChanged. This interface gives you the possibility to get notified when the value of a property changes.
public class SomeData: INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private void SetProperty<T>(ref T field, T value, [CallerMemberName] string name = "") {
if (!EqualityComparer<T>.Default.Equals(field, value)) {
field = value;
var handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(name));
}
}
}
private boolean _someBoolean;
public int SomeBoolean {
get { return _someBoolean; }
set {
SetProperty(ref _someBoolean, value);
}
}
private string _someString;
public string SomeString {
get { return _someString; }
set {
SetProperty(ref _someString, value);
}
}
// etc
}
Now our form, which uses the data class and it's INotifyPropertyChanged implementation to get notified when a change in data occurs.
public partial class SomeForm: Form {
private SomeData _data;
private void LoadData() {
_data = new SomeData();
_data.PropertyChanged += Data_PropertyChanged;
}
private void SaveData() {
// TODO: Save data
}
private void AddDataBindings() {
checkbox1.DataBindings.Add("Checked", _data, "SomeBoolean");
textbox1.DataBindings.Add("Text", _data, "SomeString");
// add other
}
private void Data_PropertyChanged(object sender, PropertyChangedEventArgs e) {
// Here you can add actions that must be triggered when some data changes.
if (e.PropertyName == "SomeBoolean") {
// Do something when some-boolean property changes
}
// Set is-changed-boolean to true to 'remember' that something has changed.
_isChanged = true;
// Give message
MessageBox.Show(string.Format("Data changed, property {0}", e.PropertyName));
}
private bool _isChanged = false;
protected void Form_Closed(object sender, EventArgs e) {
// If data is changed, save it
if (_isChanged) {
SaveData();
}
}
}
Your problem is not known where the method DataChanged use and how. I have a suggestion for you that is use Focus Activated in properties.Add datachanged printing method Activated
good luck.
You must make properties this like
I'm currently creating an application in C# using Visual Studio. I want to create some code so that when a variable has a value of 1 then a certain piece of code is carried out.
I know that I can use an if statement but the problem is that the value will be changed in an asynchronous process so technically the if statement could be ignored before the value has changed.
Is it possible to create an event handler so that when the variable value changes an event is triggered? If so, how can I do this?
It is completely possible that I could have misunderstood how an if statement works! Any help would be much appreciated.
Seems to me like you want to create a property.
public int MyProperty
{
get { return _myProperty; }
set
{
_myProperty = value;
if (_myProperty == 1)
{
// DO SOMETHING HERE
}
}
}
private int _myProperty;
This allows you to run some code any time the property value changes. You could raise an event here, if you wanted.
You can use a property setter to raise an event whenever the value of a field is going to change.
You can have your own EventHandler delegate or you can use the famous System.EventHandler delegate.
Usually there's a pattern for this:
Define a public event with an event handler delegate (that has an argument of type EventArgs).
Define a protected virtual method called OnXXXXX (OnMyPropertyValueChanged for example). In this method you should check if the event handler delegate is null and if not you can call it (it means that there are one or more methods attached to the event delegation).
Call this protected method whenever you want to notify subscribers that something has changed.
Here's an example
private int _age;
//#1
public event System.EventHandler AgeChanged;
//#2
protected virtual void OnAgeChanged()
{
if (AgeChanged != null) AgeChanged(this,EventArgs.Empty);
}
public int Age
{
get
{
return _age;
}
set
{
//#3
_age=value;
OnAgeChanged();
}
}
The advantage of this approach is that you let any other classes that want to inherit from your class to change the behavior if necessary.
If you want to catch an event in a different thread that it's being raised you must be careful not to change the state of objects that are defined in another thread which will cause a cross thread exception to be thrown. To avoid this you can either use an Invoke method on the object that you want to change its state to make sure that the change is happening in the same thread that the event has been raised or in case that you are dealing with a Windows Form you can use a BackgourndWorker to do things in a parallel thread nice and easy.
The .NET framework actually provides an interface that you can use for notifying subscribers when a property has changed: System.ComponentModel.INotifyPropertyChanged. This interface has one event PropertyChanged. Its usually used in WPF for binding but I have found it useful in business layers as a way to standardize property change notification.
In terms of thread safety I would put a lock under in the setter so that you don't run into any race conditions.
Here are my thoughts in code :) :
public class MyClass : INotifyPropertyChanged
{
private object _lock;
public int MyProperty
{
get
{
return _myProperty;
}
set
{
lock(_lock)
{
//The property changed event will get fired whenever
//the value changes. The subscriber will do work if the value is
//1. This way you can keep your business logic outside of the setter
if(value != _myProperty)
{
_myProperty = value;
NotifyPropertyChanged("MyProperty");
}
}
}
}
private NotifyPropertyChanged(string propertyName)
{
//Raise PropertyChanged event
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class MySubscriber
{
private MyClass _myClass;
void PropertyChangedInMyClass(object sender, PropertyChangedEventArgs e)
{
switch(e.PropertyName)
{
case "MyProperty":
DoWorkOnMyProperty(_myClass.MyProperty);
break;
}
}
void DoWorkOnMyProperty(int newValue)
{
if(newValue == 1)
{
//DO WORK HERE
}
}
}
Hope this is helpful :)
just use a property
int _theVariable;
public int TheVariable{
get{return _theVariable;}
set{
_theVariable = value;
if ( _theVariable == 1){
//Do stuff here.
}
}
}
2022
you can use generic class:
class Wrapped<T> {
private T _value;
public Action WillChange;
public Action DidChange;
public T Value
{
get => _value;
set
{
if ( _value != value )
{
OnWillChange();
_value = value;
OnDidChanged();
}
}
}
protected virtual void OnWillChange() => WillChange?.Invoke();
protected virtual void OnDidChange() => DidChange?.Invoke();
}
and will be able to do the following:
var i = new Wrapped<int>();
i.WillChange += () => { Console.WriteLine("will be changed!"); };
i.DidChange += () => { Console.WriteLine("changed!"); };
i.Value = 10;
i.Value = 11;
i.Value = 10;
i.Value = 11;
Console.ReadKey();
result:
will be changed!
changed!
will be changed!
changed!
will be changed!
changed!
will be changed!
changed!
A simple method involves using the get and set functions on the variable
using System;
public string Name{
get{
return name;
}
set{
name= value;
OnVarChange?.Invoke();
}
}
private string name;
public event System.Action OnVarChange;
I am making a windows forms project in C#, in which I made a class LabelX which inherits System.Windows.Forms.Label, then added a property Mass of float type
Now, my question is how can I handle, when value of Mass is changed.
e.g.:
When user enter value zero or less than zero
I want to fire a message that "Mass can't be zero or negative"
If I am interpreting this correctly, there are two parts to this. First, you need to detect invalid values and throw exceptions. Second, you need to raise an event when the property changes. This can be achieved as follows.
private float mass;
public float Mass
{
get
{
return this.mass;
}
set
{
if (value <= 0.0F)
{
throw new ArgumentOutOfRangeException("Mass cannot be zero or negative.");
}
if (this.mass != value)
{
this.mass = value;
OnMassChanged(EventArgs.Empty);
}
}
}
public event EventHandler MassChanged;
protected virtual void OnMassChanged(EventArgs args)
{
var handler = this.MassChanged;
if (handler != null)
{
handler(this, args);
}
}
To show a message if an invalid entry is made, you should put a try \ catch block around the call to set Mass and catch the ArgumentOutOfRangeException.
Try the following:
// Created an empty form with a LabelX control on it.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// Added this event from the property manager.
private void labelX1_MassChanged(object sender, EventArgs e)
{
var label = (LabelX)sender;
if (label.Mass <= 0.0)
MessageBox.Show("Mass is less than or equal to 0");
}
}
public class LabelX : Label
{
private float _mass;
public float Mass
{
get { return _mass; }
set
{
if (!value.Equals(_mass))
{
_mass = value;
OnMassChanged(EventArgs.Empty);
}
}
}
public event EventHandler MassChanged;
protected virtual void OnMassChanged(EventArgs e)
{
if (MassChanged != null)
MassChanged(this, e);
}
}
Outside of your LabelX class, create the following class:
public class MassChangedEventArgs : EventArgs
{
public float Mass { get; private set; }
public MassChangedEventArgs(float mass)
{
this.Mass = mass;
}
}
Also outside of your LabelX class, create the following delegate. This will be your event handler.
public delegate void MassChangedEventHandler(object sender, MassChangedEventArgs e);
Within your LabelX class, create an event to broadcast:
public class LabelX
{
public event MassChangedEventHandler MassChanged;
//the rest of your code here...
}
You'll also want to create a private instance method that will fire your event.
public class LabelX
{
public event MassChangedEventHandler MassChanged;
private void OnMassChanged()
{
if(MassChanged!=null)
this.MassChanged(this, new MassChangedEventArgs(this.Mass));
}
//the rest of your code here...
}
Finally, whenever your Mass property changes, call OnMassChanged. For instance:
public class LabelX
{
private float mass;
public float Mass
{
get
{
return mass;
}
set
{
mass = value;
OnMassChanged();
}
}
public event MassChangedEventHandler MassChanged;
private void OnMassChanged()
{
if(MassChanged!=null)
this.MassChanged(this, new MassChangedEventArgs(this.Mass));
}
//the rest of your code here...
}
When you want to handle that event on a per-instance basis, you just have to register a listener with the MassChanged event of your underlying object and perform whatever actions are necessary.
Events are a common pattern used in the framework. The process typically involves defining a delegate to be used as the event handlers, declaring the event using the handler, defining methods to raise the event, then hooking up to the properties the logic to raise the event.
The message you describe is better done as an Exception but here's an example to define the MassChanged event.
// Define event args if you have additional
// information to pass to your event handlers
public class MassChangedEventArgs : EventArgs
{
public MassChangedEventArgs(int oldMass)
{
OldMass = oldMass;
}
public int OldMass { get; private set; }
}
public class SomeObject
{
// There's a generic event handler delegate that can be
// used so you only need to define the event arguments.
public event EventHandler<MassChangedEventArgs> MassChanged;
// Convenience method to raise the event
protected virtual void OnMassChanged(MassChangedEventArgs e)
{
if (MassChanged != null)
MassChanged(this, e);
}
public int Mass
{
get
{
return mass;
}
set
{
// Your checks here
if (value <= 0)
throw new ArgumentOutOfRangeException("Mass", "Mass can't be zero or negative");
// Should only raise the event if the new value is different
if (value != mass)
{
// Change the mass
MassChangedEventArgs e = new MassChangedEventArgs(mass);
mass = value;
// Raise the event
OnMassChanged(e);
}
}
}
private int mass;
}
After that, it's just a matter of registering handlers to the event and going from there.
I am quite sure you you would like to 'fire' an exception in your case.
This more of a validation logic issue such AOP code contracts concept.
But if you really like to create an event for it you have to at least:
1) create an event storage variable in your label class
public event EventHandler MassChanged;
2) in your property (note that you loose the ability to use code gen functions of c# 3 for
which 'auto' implement the field to store your Mass property value)
public bool Mass
{
get { return _mass; }
set {
// check if value is invalid (0 or less) && that event subscribers exist
if(value<=0 && MassChanged != null) { MassChanged(this, null); }
else // otherwise assign ...
{
_mass = value;
}
}
}
3) create an event handler of type EventHandler
Best to read the msdn article for events: link text
Again I am pretty sure you are not handling exceptions properly in the app
if you need an event for this. I mean there is nothing wrong but events are
usually not used as means of value validations.
Is there a way to programmatically generate a click event on a CheckBox? I am looking for an equivalent to Button.PerformClick();
Why do you need to simulate a click, doesn't this line of code fits your need?
myCheckBox.Checked = !myCheckBox.Checked;
If you need to execute logic when the state of the CheckBox changes, you should use CheckedChanged event instead of Click.
private void CheckBox1_CheckedChanged(Object sender, EventArgs e)
{
MessageBox.Show("You are in the CheckBox.CheckedChanged event.");
}
Those solutions above calls Checkbox.CheckedChanged event.
If you want to explicitly call Click event you can this:
checkBox1_Click(checkBox1, null);
Why do you want to generate a click event on the CheckBox?
If you want to toggle it's value:
theCheckBox.Checked = !theCheckBox.Checked;
If you want to trigger some functionality that is connected to the Click event, it's a better idea to move the code out from the Click event handler into a separate method that can be called from anywhere:
private void theCheckBox_Click(object sender, EventArgs e)
{
HandleCheckBoxClick((CheckBox)sender);
}
private void HandleCheckBoxClick(CheckBox sender)
{
// do what is needed here
}
When you design your code like that, you can easily invoke the functionality from anywhere:
HandleCheckBoxClick(theCheckBox);
The same approach can (and perhaps should) be used for most control event handlers; move as much code as possible out from event handlers and into methods that are more reusable.
I'm still setting up a new workstation so I can't research this properly at the moment, but with UI Automation maybe it's possible that the checkbox supports the IInvokeProvider and you can use the Invoke method?
I don't think you can generate a click event in that way without calling the checkBox_Click event handler directly. But you can do this:
checkBox.Checked = !checkBox.Checked;
The CheckedChanged handler will still be called even if you do this.
The Button PerformClick() method validates the active control, testing whether the active control can lose the current focus. There are two ways to possibly do the same thing for a CheckBox. Approach #1 is to use reflection to call the methods that are internal to the Control class:
public class CheckBoxPerformClick : CheckBox {
private readonly static MethodInfo callValidateActiveControl;
private readonly static PropertyInfo propValidationCancelled;
static CheckBoxPerformClick() {
try {
Type ty = typeof(Control);
Type outBool = Type.GetType("System.Boolean&");
callValidateActiveControl = ty.GetMethod("ValidateActiveControl", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { outBool }, null);
propValidationCancelled = ty.GetProperty("ValidationCancelled", BindingFlags.Instance | BindingFlags.NonPublic);
} catch {}
}
public CheckBoxPerformClick() : base() {
this.Text = "Checkbox";
this.Appearance = Appearance.Button;
}
public void PerformClick() {
if (callValidateActiveControl != null && propValidationCancelled != null) {
try {
Object[] args = new Object[1];
bool validate = (bool) callValidateActiveControl.Invoke(this, args);
bool validatedControlAllowsFocusChange = (bool) args[0];
if (validate || validatedControlAllowsFocusChange) {
bool cancelled = (bool) propValidationCancelled.GetValue(this);
if (!cancelled) {
ResetFlagsandPaint();
OnClick(EventArgs.Empty);
}
}
} catch {
}
}
}
}
Approach #2 tries to do the same thing, but without reflection:
public class CheckBoxPerformClick2 : CheckBox {
public CheckBoxPerformClick2() : base() {
this.Text = "Checkbox";
this.Appearance = Appearance.Button;
}
public void PerformClick() {
bool validate = CanPerformClick();
if (validate) {
ResetFlagsandPaint();
OnClick(EventArgs.Empty);
}
}
// before allowing a click, make sure this control can receive the focus, and that other controls don't require validation
public bool CanPerformClick() {
if (!CanSelect)
return false;
Control c = this.Parent;
while (c != null) {
if (c is ContainerControl)
break;
c = c.Parent;
}
bool valid = true;
if (c is ContainerControl) {
var cc = (ContainerControl) c;
valid = cc.Validate(true);
}
return valid;
}
}
Say I have a box that says ENABLED or DISABLED.
How can I make the text vary depending on a state?
public void CheckBox1CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked) {
checkBox1.Text = "Enabled";
}
else {
checkBox1.Text = "Disabled";
}
}
box.Text = (box.Enabled ? "ENABLED" : "DISABLED");
If I understand correctly, you are asking how to have a label or some other bit of UI text automatically update to reflect a "state variable". This is just one way to accomplish what you're describing:
I would do it by having a central state object which implements INotifyPropertyChanging and INotifyPropertyChanged. When your application initializes, attach event handlers to the events those interfaces expose, and one of those event handlers can change the text of the label when property (Foo) changes.
public class State : INotifyPropertyChanging, INotifyPropertyChanged
{
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanging(PropertyChangingEventArgs e)
{
if (this.PropertyChanging != null)
{
this.PropertyChanging(this, e);
}
}
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, e);
}
}
public bool Foo
{
get
{
return foo;
}
set
{
if (value != foo)
{
this.OnPropertyChanging(new PropertyChangingEventArgs("Foo"));
foo = value;
this.OnPropertyChanged(new PropertyChangedEventArgs("Foo"));
}
}
}
private bool foo = false;
}
protected void HandleStateChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == "Foo")
{
box.Text = state.Foo ? "Enabled" : "Disabled";
}
}
What jeffamaphone said, but I should add that any time that state changes you will have to make sure to run that same code. The easiest way to insure this happens is by binding the box.Text property to the state object that you are interested in. That way, any change made to the object is immediately reflected in the text.
This blog post
helped me get started with data binding.... because I love FAQs.
The last few months I have been going with a slightly lighter weight solution than implementing a whole class to manage state. I usually define an enum which indicates the types of states available in the UI, then I have a function that makes changes to the UI, based on the state selected. This approach has been very successful, and not too heavy in terms of the amount of code needed to be written.
If I want to know what states are available in the UI, I can check the values of the enum.
public enum SystemState
{
/// <summary>
/// System is under the control of a remote logging application.
/// </summary>
RemoteMode,
/// <summary>
/// System is not under the control of a remote logging application.
/// </summary>
LocalMode
}
public interface IView
{
void SetState(SystemState state);
}
//method on the UI to modify UI
private void SetState(SystemState state)
{
switch (state)
{
case SystemState.LocalMode:
//for now, just unlock the ui
break;
case SystemState.RemoteMode:
//for now, just lock the ui
break;
default:
throw new Exception("Unknown State requested:" + state);
}
}
//now when you change state, you can take advantage of intellisense and compile time checking:
public void Connect()
{
SetState(SystemState.RemoteMode);
}