Using delegate event handler to get data from UserControl to Form - c#

I have a WinForm, and add a UserControl with a DataGridView.
Now I want to do a doubleClick on the DataGridView and get the object data to my Form.
In my UserControl:
public event DataGridViewCellEventHandler dg_CellDoubleClickEvent;
private void dg_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex != -1)
{
try
{
Cursor.Current = Cursors.WaitCursor;
Address a = dg.Rows[e.RowIndex].DataBoundItem as Address;
if (a != null)
{
// how can I pass my Address object??
dgAngebote_CellDoubleClickEvent?.Invoke(this.dgAngebote, e);
}
}
finally { Cursor.Current = Cursors.Default; }
}
}
In my Form:
private void FormAddress_Load(object sender, EventArgs e)
{
uc.dg_CellDoubleClickEvent += new DataGridViewCellEventHandler(myEvent);
}
private void myEvent(object sender, DataGridViewCellEventArgs e)
{
MessageBox.Show("test");
}
My MessageBox is shown. This is ok, but I want to geht my Address to show.
Is this the right way of doing that? How?
Kind regards.

You can change the delegate to one you define or use the generic form of System.Action. There is also the option to use EventHandler and define your own event args class that you can add properties and logic to.
Below is an example using the Action delegate, with T being your Address type.
public event Action<Address> OnAddressSelected;
...
Address address = dg.Rows[e.RowIndex].DataBoundItem as Address;
if (address != null)
{
OnAddressSelected?.Invoke(address);
}
And in the form
private void FormAddress_Load(object sender, EventArgs e)
{
uc.OnAddressSelected += OnAddressSelected;
}
private void OnAddressSelected(Address address)
{
MessageBox.Show($"Address: {address}");
}

Related

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
}

EventHandler for all controls in form

In my code I want to perform some actions when some controls are focused. So instead of having one handler for each control i was wondering if there could be any way of adding all controls to the handler and inside the handler function perform the desired action.
I have this:
private void tb_page_GotFocus(Object sender, EventArgs e)
{
tb_page.Visible = false;
}
private void tb_maxPrice_GotFocus(Object sender, EventArgs e)
{
tb_maxPrice.Text = "";
}
private void tb_maxPrice_GotFocus(Object sender, EventArgs e)
{
tb_maxPrice.Text = "";
}
I want this:
private void AnyControl_GotFocus(Object sender, EventArgs e)
{
if(tb_page.isFocused == true)
{
...
}
else if (tb_maxPrice.isFocused == true)
{
...
}
else
{
...
}
}
Is this possible? How could I do it? Thanks a lot.
Iterate your controls in your form or panel and subscribe to their GotFocus Event
private void Form1_Load(object sender, EventArgs e)
{
foreach (Control c in this)
{
c.GotFocus += new EventHandler(AnyControl_GotFocus);
}
}
void AnyControl_GotFocus(object sender, EventArgs e)
{
//You'll need to identify the sender, for that you could:
if( sender == tb_page) {...}
//OR:
//Make sender implement an interface
//Inherit from control
//Set the tag property of the control with a string so you can identify what it is and what to do with it
//And other tricks
//(Read #Steve and #Taw comment below)
}

Custom user control doesn't catch any mouse events in c#

I create a custom user control and use that in my form.
but it does not capture any mouse event!
what is the problem?
thanks
Define the event in your custom control
private delegate void MyClickEvent(object sender, EventArgs e);
public event MyClickEvent MyClick;
public void OnMyClickEvent(object sender, EventArgs e)
{
if (MyClick != null)
MyClick(sender, e);//execute event
}
Now in MainForm
public partial class Form1
{
public Form1()
{
myCustomButton.MyClick += FireThisOnClick;
}
private void FireThisOnClick(object sender, EventArgs e)
{
//this will be executed on click
}
}

how to run the event of user control not regular

I have a user control with some buttons (tmNewItem, tmEdit, tmInsert)
I write a clickButton event for them.
for example:
public void btnEdit_Click(object sender, EventArgs e)
{
btnNew.Enabled = false;
btnEdit.Enabled = false;
}
I used this user control in another project and write another method for the buttons and assign it to the usr control:
public void DTedit(object sender, EventArgs e)
{
}
private void UserControl_Load(object sender, EventArgs e)
{
DT_Navigator.btnCancel.Click += new EventHandler(DTedit);
}
and now, when I run the project and press btnEdit button, the first time, btnEdit_Click will execute and after that DTedit. can i change it? I mean the first time DTedit (that I define it in my project) run, and after it btnEdit_Click (that I define it in the user control) run?
how can I do that?
Try this
public void DTedit(object sender, EventArgs e)
{
//Place your code here
DT_Navigator.btnCancel.Click -= new EventHandler(DTedit); //This will remove handler from the button click and it will not be executed next time.
}
private void UserControl_Load(object sender, EventArgs e)
{
DT_Navigator.btnCancel.Click += new EventHandler(DTedit);
}
Suggested Code
//User control
public event CancelEventHandler BeginEdit;
public event EventHandler EndEdit;
private btnYourButton_Click(object sender, EventArgs e)
{
CancelEventArgs e = new CancelEventArgs();
e.Cancel = false;
if (BeginEdit != null)
BeginEdit(this, e);
if (e.Cancel == false)
{
if (EndEdit != null)
EndEdit(this, new EventArgs);
//You can place your code here to disable controls
}
}

.net cf TextBox that displays keyboard on focus

I have a few text boxes on my UI that I want to display the mobile keyboard for when the control has focus, then go away.
Note: for this particular program, it is a tall screen and has no physical keyboard on the device.
Add an InputPanel to your Form, hook up the GotFocus and LostFocus events of the TextBox and show/hide the input panel in the event handlers:
private void TextBox_GotFocus(object sender, EventArgs e)
{
SetKeyboardVisible(true);
}
private void TextBox_LostFocus(object sender, EventArgs e)
{
SetKeyboardVisible(false);
}
protected void SetKeyboardVisible(bool isVisible)
{
inputPanel.Enabled = isVisible;
}
Update
In response to ctacke's request for completeness; here is sample code for hooking up the event handlers. Normally I would use the designer for this (select the textbox, show the property grid, switch to the event list and have the environment set up handlers for GotFocus and LostFocus), but if the UI contains more than a few text boxes you may wish to have it more automated.
The following class exposes two static methods, AttachGotLostFocusEvents and DetachGotLostFocusEvents; they accept a ControlCollection and two event handlers.
internal static class ControlHelper
{
private static bool IsGotLostFocusControl(Control ctl)
{
return ctl.GetType().IsSubclassOf(typeof(TextBoxBase)) ||
(ctl.GetType() == typeof(ComboBox) && (ctl as ComboBox).DropDownStyle == ComboBoxStyle.DropDown);
}
public static void AttachGotLostFocusEvents(
System.Windows.Forms.Control.ControlCollection controls,
EventHandler gotFocusEventHandler,
EventHandler lostFocusEventHandler)
{
foreach (Control ctl in controls)
{
if (IsGotLostFocusControl(ctl))
{
ctl.GotFocus += gotFocusEventHandler;
ctl.LostFocus += lostFocusEventHandler ;
}
else if (ctl.Controls.Count > 0)
{
AttachGotLostFocusEvents(ctl.Controls, gotFocusEventHandler, lostFocusEventHandler);
}
}
}
public static void DetachGotLostFocusEvents(
System.Windows.Forms.Control.ControlCollection controls,
EventHandler gotFocusEventHandler,
EventHandler lostFocusEventHandler)
{
foreach (Control ctl in controls)
{
if (IsGotLostFocusControl(ctl))
{
ctl.GotFocus -= gotFocusEventHandler;
ctl.LostFocus -= lostFocusEventHandler;
}
else if (ctl.Controls.Count > 0)
{
DetachGotLostFocusEvents(ctl.Controls, gotFocusEventHandler, lostFocusEventHandler);
}
}
}
}
Usage example in a form:
private void Form_Load(object sender, EventArgs e)
{
ControlHelper.AttachGotLostFocusEvents(
this.Controls,
new EventHandler(EditControl_GotFocus),
new EventHandler(EditControl_LostFocus));
}
private void Form_Closed(object sender, EventArgs e)
{
ControlHelper.DetachGotLostFocusEvents(
this.Controls,
new EventHandler(EditControl_GotFocus),
new EventHandler(EditControl_LostFocus));
}
private void EditControl_GotFocus(object sender, EventArgs e)
{
ShowKeyboard();
}
private void EditControl_LostFocus(object sender, EventArgs e)
{
HideKeyboard();
}
Use the InputPanel class. Enable it when you get focus, disable it when you lose focus.

Categories