event not being fired - c#

I have made a custom dialog window that inherits ChildWindow
public partial class InputWindow : ChildWindow
{
public InputWindow()
{
InitializeComponent();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("clicked");
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
private void inputTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
this.OKButton_Click(this, new RoutedEventArgs());
}
}
When I press enter in the tetxbox the event OKButton_Click gets fired ( because message box appears). However, the code (Add Folder) in the event handler below that exists in another class does not get fired! even though the message box appears! Why is this so? and How can I fix it?
InputWindow win = new InputWindow();
win.Title = "Enter New Folder Name";
win.OKButton.Click += (s, e) =>
{
if (!string.IsNullOrWhiteSpace(win.inputTextBox.Text))
{
AddNewFolder(win.inputTextBox.Text);
win.DialogResult = true;
}
};
win.Show();

You're just calling OKButton_click directly from your KeyDown event handler. That's not the same as raising the Click event on the OK button itself - it's just a method call. So it's no wonder that other event handlers for OKButton.Click aren't being called.
I don't know of any way of manually raising the Click event yourself. It sounds like really you should have one common method which is called from both the Click event handler and the KeyDown event handler.

Related

Event bubbling inside UserControl in C#

I've created a custom UserControl, it's a button with a grid inside it.
From the Page that contains it, MainPage.xaml, I need to bind a Click event to the UserControl, and the function for the EventHandler must be written outside, in the MainPage (not inside the UserControl).
So, reading through this question, I've created an Event and a EventHandler function that triggers the event. These are inside the UserControl.
This are the classes
UserControl.xaml.cs
public class MyButton : UserControl
{
public event RoutedEventHandler ButtonClicked;
private void ButtonClickedHandler()
{
//Null check makes sure the main page is attached to the event
if (this.ButtonClicked != null)
this.ButtonClicked(this, new RoutedEventArgs());
Debug.WriteLine("ButtonClickedHandler");
}
}
MainPage.xaml.cs
private void MyButton_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("MyButton_Click");
}
private void MyButton_Loaded(object sender, RoutedEventArgs e)
{
(sender as MyButton).ButtonClicked += MyButton_Click;
}
As you can see, I've placed a couple of Debug.WriteLine, but they don't get triggered, and I don't know what I'm doing wrong.
Just having a single method in your code that is never called by anything will not make your program work. You will first have to call the ButtonClickedHandler() method each time your button is clicked.
To do that, just register a method for the click-event of your button in your xaml file.
<Button Content="This Is Your Button" Click="YourButtonClick"/>
And then call the ButtonClickedHandler() method in there:
private void YourButtonClick(object sender, RoutedEventArgs e) {
ButtonClickedHandler();
}
A simpler way to solve the problem is using an event property:
UserControl.xaml.cs
public Event RoutedEventHandler ButtonClicked
{
add {
ButtonName.Click += value; //use the name of your button here
}
remove {
ButtonName.Click -= value;
}
}
And then you can simply register to that event in your MainWindow:
private void MyButton_Loaded(object sender, RoutedEventArgs e)
{
(sender as MyButton).ButtonClicked += MyButton_Click;
}
By the way, I think it is better to register the event in the xaml file where you also create the control:

checkbox.Checked dosent update on other forms

I have 2 forms, UserInterface and Client I'm passing checkbox2.Checked info to Client but it only works however it was at launch. When I tick or untick and close and reopenClient it wont notice the change.
Modifiers is Public on checkbox2 at UserInterface form.
Here is Client code:
public partial class Client : Form
{
private UserInterface ui1;
public Client()
{
InitializeComponent();
}
public void CheckBoxCheck()
{
if (ui1.checkBox2.Checked == true)
{
MessageBox.Show("true");
}
else
{
MessageBox.Show("false");
}
}
}
If the checkbox is ticked at launch Client will show "true" but if I click it (untick) and run Client it will still show "true".
What do I need to add or modify so checkbox2 will be updated in realtime. Thank you.
Note: I'm pretty new with coding, explanations are appreciated.
I'll be building on noMad17's answer, you have to subscribe to your CheckBox event in your UserInterface form. But the change is that now we will send the CheckBox that was clicked in the event. So this code is for your UserInterface form:
public event EventHandler SomeEvent;
protected void OnSomeEvent(object sender, EventArgs e)
{
EventHandler eh = SomeEvent;
if(eh != null)
{
eh(sender, e);
}
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
OnSomeEvent(sender, e);
}
Now for the Client, it needs to know what a UserInterface is so we have to pass UserInterface to the Client in the constructor, otherwise it won't initialize. Also here we are gonna work out the CheckBox event that the parent form is gonna give us. And in the end we have to unsubscribe the event. So this code is for your Client:
public partial class Client : Form
{
private UserInterface ui1;
public Client(UserInterface ui1)
{
InitializeComponent();
this.ui1 = ui1;
ui1.SomeEvent += UI1_SomeEvent;
}
private void UI1_SomeEvent(object sender, EventArgs e)
{
//Your code...
CheckBox c = sender as CheckBox;
if(c.Checked == true)
{
MessageBox.Show("true");
}
else
{
MessageBox.Show("false");
}
}
private void Client_FormClosing(object sender, FormClosingEventArgs e)
{
ui1.SomeEvent -= UI1_SomeEvent;
}
}
Your Forms should be connected. It looks like ui1 is a different instance of UserInterface form.
There are different approaches to pass the data between forms and it depends on your demands.
For instance you could create UserInterface form inside of Client. And use the Show() method to show it.
You should probably be making use of the Checkbox.Checked event inside UserInterface class and then fire a custom event that your Client can subscribe to.
public event EventHandler<EventArgs> CheckboxCheckedChanged;
protected void OnCheckboxCheckedChanged(EventArgs e)
{
if (CheckboxCheckedChanged != null)
CheckboxCheckedChanged(this, e);
}
private void checkbox2_CheckedChanged(object sender, EventArgs e)
{
OnCheckboxCheckedChanged(e);
}
And then in Client:
ui1.CheckboxCheckedChanged += ui1_CheckboxCheckedChanged;
private void ui1_CheckboxCheckedChanged(object sender, CheckBoxEventArgs e)
{
// Your code here
}

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);

Assign event handler to method

how can I assign the Form closing event to the menustrip item click method ?
this.Closing += new CancelEventHandler(this.Form1_Closing);
private void Form1_Closing(object sender, CancelEventArgs e)
{
//
}
private void izlazToolStripMenuItem_Click(object sender, EventArgs e)
{
//
}
thanks
You probably want to close the the Form in click event, so:
private void izlazToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
This will trigger Closing event.
Another way you could hook up the Close method to the Click event on your menu item is through the use of a lambda expression. The following code in the form's constructor demonstrates this:
public Form1()
{
InitializeComponent();
this.izlazToolStripMenuItem.Click += (s, a) => this.Close();
}
More information on lambda expressions can be found here: http://msdn.microsoft.com/en-us/library/vstudio/bb397687.aspx

how to set a custom control button's job after adding it to some form?

Im making a userControl named [File_Manager] and i was wondering if i can add a button to this custom control that i can set its job later after adding this custom control to another form .. something like
File_Manager fManager = new File_Manager();
fManager.SetFreeButtonJob( MessageBox.Show("Hello") ); // something like this.
then whenever user press that button .. the messageBox shows up.
So.. Is it possible to do that?
thanks in advance.
Sure you can. Just attach the buttons click handler to the action you pass in.
fManager.SetFreeButtonJob(() => MessageBox.Show("Hello"));
private void SetFreeButtonJob(Action action)
{
button1.Click += (s,e) => action();
}
Just note that passing in the Action breaks the encapsulation of user control though. You should probably do something like SetFreeButtonJob(Jobs.SayHello); and put the knowledge of what to do inside the control.
Create a custom event for your UserControl and fire it when your Button is clicked. You can then attach an event handler to the custom event in your Form. Or you can just raise the UserControl's Click Event when your Button is clicked.
public delegate void CustomClickEventHandler(object sender, EventArgs e);
public partial class buttonTest : UserControl
{
public event CustomClickEventHandler CustomClick;
public buttonTest()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
CustomClick(sender, e);
}
}
and in your Form
public Form1()
{
InitializeComponent();
buttonTest1.CustomClick +=new CustomClickEventHandler(userControl1_ButtonClick);
}
private void userControl1_ButtonClick(object sender, EventArgs e)
{
MessageBox.Show("Hello");
}
Or as my second option try.
private void button2_Click(object sender, EventArgs e)
{
OnClick(e);
}
and in your Form subscribe to the UserControl's Click event.
buttonTest1.Click +=new EventHandler(buttonTest1_Click);
private void buttonTest1_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello Again");
}

Categories