Is there any way not to call Control Event? - c#

Let's say there is event ComboBox_SelectedIndexChange something like this
private void MyComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
//do something//
}
And i have a function which changes value of ComboBox.
Private void MyFunction()
{
MyComboBox.Text = "New Value";
}
Can i make MyFunction prevent from calling the event MyComboBox_SelectedIndexChanged while changing the value of MyComboBox?

Can i make MyFunction prevent from calling the event MyComboBox_SelectedIndexChanged while changing the value of MyComboBox?
No, you cannot. You have two fundamental options, both of which accomplish the same thing:
You can unhook the event handler method from the control, set the value, and then reattach the event handler method to the control. For example:
private void MyFunction()
{
MyComboBox.SelectedIndexChanged -= MyComboBox_SelectedIndexChanged;
MyComboBox.Text = "New Value";
MyComboBox.SelectedIndexChanged += MyComboBox_SelectedIndexChanged;
}
You can declare a class-level field that will keep track of whether the value was updated programmatically or by the user. Set the field when you want to update the combo box programmatically, and verify its value in the SelectedIndexChanged event handler method.
For example:
private bool allowComboBoxChange = true;
private void MyComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (allowComboBoxChange)
{
//do something
}
}
private void MyFunction()
{
allowComboBoxChange = false;
MyComboBox.Text = "New Value";
allowComboBoxChange = true;
}

You may attach or detach an event handler.
//attach the handler
MyComboBox.SelectedIndexChanged+=(sender,eventArgs)=>
{
//code
};
//detach the handler
MyComboBox.SelectedIndexChanged-=(sender,eventArgs)=>
{
//code
};
Or
Private void MyFunction()
{
comboBox1.SelectedIndexChanged -= new EventHandler(TestIt);
MyComboBox.Text = "New Value";
comboBox1.SelectedIndexChanged += new EventHandler(TestIt);
}
private void TestIt(object sender, EventArgs e)
{
//do something//
}

Related

Is it possible to let only a user selection trigger a SelectionChanged event on a DataGridView?

SelectionChanged methods are triggered when the selection is changed by program. So, for example, calling dataGridView.ClearSelection() or dataGridView.Rows[0].Selected = true would call the method
private void dataGridView_SelectionChanged(object sender, EventArgs e)
{
}
Is it possible to execute code only when the user changed the selection, e.g. by selecting a row/cell with the mouse or keyboard?
You will have to code this in
private bool _programmaticChange;
private void SomeMethod()
{
_programmaticChange = true;
dataGridView.ClearSelection();
_programmaticChange = false;
}
private void dataGridView_SelectionChanged(object sender, EventArgs e)
{
if (_programmaticChange) return;
// some code
}
this will make it run only on user actions

Detecting checkbox touch

What method is to be used in order to detect whether a checkbox was touched by a user to change the isChecked status in my windows phone app? In my code I manually set a checkbox on start up and the callback gets fired right away, while I only want to fire the callback if the user interacted with the view.
public CheckBoxPage()
{
InitializeComponent();
AvailableCheckBox.IsChecked = true; //name of the checkbox
}
private void CheckBox_Checked(object sender, RoutedEventArgs e)//event handler
{
MessageBox.Show("Changed");
}
Use a variable to keep track of whether the page is loaded or not and only have the handler do stuff if it's loaded.
private bool _isLoaded = false;
public CheckBoxPage()
{
InitializeComponent();
AvailableCheckBox.IsChecked = true;
_isLoaded = true; // enable the AvailableCheckBox_Checked handler
}
void AvailableCheckBox_Checked(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return; // stop here if not loaded yet
// everything is loaded so let's execute some stuff
MessageBox.Show("Changed");
}
Use the Click method:
private void AvailableCheckBox_Click(object sender, RoutedEventArgs e)
{
if (AvailableCheckBox.IsChecked == true)
{
// Checked
}
}
Add the handler after you've decided if the Checkbox should be checked.
public CheckBoxPage()
{
InitializeComponent();
AvailableCheckBox.IsChecked = true;
AvailableCheckBox.Checked += AvailableCheckBox_Checked;
}
void AvailableCheckBox_Checked(object sender, RoutedEventArgs e)
{
MessageBox.Show("Changed");
}

How can I make a winform button "do something" as long as I am pressing the button?

I have tried all day, and looked up all kinds of ideas... with no real help.
When I press a button, like "JOG", which would move a CNC Machine axis continuously, as long a the button is pressed, then when released, it would stop.
To test this I am using a "picuture / LED" which when I press and hold, should be on... and when I release, it should turn off.
Pressed Button should = only while pressed, do something.
Release of same button = stop doing whatever you were doing now.
I am sure for you advanced folks, this is maybe 101... but for me... it is eating my lunch... help?
You can use the MouseDown and MouseUp events. When the MouseDown event is hit, call a method that loops and performs your action. Once MouseUp is hit, stop the loop.
private bool _run = false;
public void button_MouseDown(object sender, EventArgs e)
{
_run = true;
MyAction();
}
public void button_MouseUp(object sender, EventArgs e)
{
_run = false;
}
public void MyAction()
{
while(_run)
{
//You actions
}
}
Note that the above example will hog up the UI thread. You should run it on another thread using a BackgroundWorker or something similar.
Generically, have a look at the mouse up and down events. I would have it call some function asynchronously (not on the UI thread) when the mouse is down. And stop it when the mouse up event fires. System.Threading has some nice models for this. Try googling around there.
You are wanting to start and stop a thread where the procedure is looping performing your action.
I'd make my own subclass, something like this:
public class RepeatButton : Button
{
readonly Timer timer = new Timer();
public event EventHandler Depressed;
public virtual TimeSpan Interval
{
get { return TimeSpan.FromMilliseconds(timer.Interval); }
set { timer.Interval = (int)value.TotalMilliseconds; }
}
public RepeatButton()
{
timer.Interval = 100;
timer.Tick += delegate { OnDepressed(); };
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
timer.Stop();
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
timer.Start();
}
protected virtual void OnDepressed()
{
var handler = this.Depressed;
if (handler != null)
handler(this, EventArgs.Empty);
}
}
This allows your code to be asynchronous but also the Depressed event would be invoked on the UI thread still.
Consider Space bar to trigger button down and up as well.
this.button1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.button1_MouseDown);
this.button1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.button1_MouseUp);
this.button1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.button1_KeyDown);
this.button1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.button1_KeyUp);
private void button1_MouseDown(object sender, MouseEventArgs e)
{
led18.Show();
}
private void button1_MouseUp(object sender, MouseEventArgs e)
{
led18.Hide();
}
private void button1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Space && e.Alt==false && e.Control==false && e.Shift==false)
{
led18.Show();
}
}
private void button1_KeyUp(object sender, KeyEventArgs e)
{
led18.Hide();
}
Thanks all, this is about as simple as I could get it.
Button and Mouse control mixed togather, needs mouse handling... which is added in the button properties, which will add the code to the designer.
private void button2_MouseDown(object sender, MouseEventArgs e)
{
led18.Show();
}
private void button2_MouseUp(object sender, MouseEventArgs e)
{
led18.Hide();
}
//below get automatically put into the design file...
this.button1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.button1_MouseDown);
this.button1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.button1_MouseUp);

Detecting source of event and type of event using C#

I'm learning how to work with delegates and by now have got some ideas. In a C# code (below) I like to capture type of event in string. What is the best approach to get the source of event and type of event?
For name of the source I'm using sender.GetType().FullName.ToString(); if it is correct. What about event type?
Thanks.
protected virtual void OnChanged(EventArgs e)
{
if (Changed != null)
Changed(this,e);
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
OnChanged(EventArgs.Empty);
}
public EventListener(myForm theform)
{
TheForm = theform;
TheForm.Changed += new ChangedEventHandler(myMethod);
}
private void myMethod(object sender, EventArgs e)
{
string s = "hey, got notified " + sender.GetType().FullName.ToString();
MessageBox.Show(s);
}
There is no way to know which event call the function with the EventArgs class.
If you are using the prepared events (like Click event), you can create your own "Args" class like that:
public class MyEventArgs : EventArgs
{
public string EventCallerName { get; set; }
}
Then call the event like that:
if (Changed != null)
Changed(this,new MyEventArgs() { EventCallerName = "Changed" });
And in the receiver method you can see that value, like that:
private void myMethod(object sender, EventArgs e)
{
if (e is MyEventArgs)
MessageBox.Show("Event type: " + (e as MyEventType).EventCallerName);
string s = "hey, got notified " + sender.GetType().FullName.ToString();
MessageBox.Show(s);
}
But, if you are using your own event you can create your own delegate and do with it whatever you want.
You should be able to find the source of the event by using a StackTrace. I believe you'll find that events are usually fired by protected functions that have names that are similar to the event name.
Backing type for events is delegate. The event source from the event handler cannot be determined. You however can check the delegate type when you are subscribing to the event. The class defining\publishing the event will be event source and type of delegate will be event type.
May be that is right solution?:
private void Form1_FormClosed(object sender, EventArgs e)
{
var eventType = e.ToString().Split('.').Last().Replace("EventArgs", ""); //eventType = "FromClosed"
}
Assuming you want the name of the event, rather than detecting why don't you just fix it when you register the handler for the event? Something like:
public EventListener(myForm theform)
{
TheForm = theform;
TheForm.Changed += (s, e) => this.MyMethod(s, e, "Changed");
}
private void MyMethod(object sender, EventArgs e, string eventName)
{
string s = "hey, got notified " + sender.GetType().FullName.ToString();
MessageBox.Show(s);
}

c# not to call editValueChanged on form load

Due to fact that I load data from a database and place it into a DevExpress TextEdit control on FormLoad, the event handler TextEdit_EditValueChanged is called. Is it possible to make any checking in the event handler, or prevent the event from being raised?
Something like this:
bool dataLoaded = false;
private void LoadData()
{
// do the loading and set the Text property of the textEdit
dataLoaded = true;
}
private void TextEdit_EditValueChanged(object sender, EventArgs e)
{
if (dataLoaded == false) return;
// the code after this comment will run only after the data was loaded
}
Or you can add the event handler after the loading was done, like this:
private void LoadData()
{
// do the loading and set the Text property of the textEdit
TextEdit.EditValueChanged += TextEdit_EditValueChanged;
}
private void TextEdit_EditValueChanged(object sender, EventArgs e)
{
// the code after this comment will run only after the data was loaded
}
Use property
private void TextEdit_EditValueChanged(object sender, EventArgs e)
{
if (!this.IsLoaded) return;
// the code after this comment will run only after the data was loaded
}

Categories