Call a method in another class from a control within a control? - c#

I have a custom control created, comprised of a bunch of text boxes, 1 button and radio buttons.
I then have a "parent" control which only has this 1 custom control placed on it, and in the code behind I have a reference to this control's Presenter.
The presenter handles the actual code for searching (when the one button is pressed). How do I set up the button click event on the child control to call the Search method from the presenter?
So I have the following:
CtlSearchDetails
ViewSearchScreen
PresenterSearchScreen
The button click event is on CtlSearchDetails and it needs to call the method on PresenterSearchScreen. I cannot figure out how to reveal this method to the instace of the control on ViewSearchScreen.

In your custom child control, you want to expose an event for the button click:
public event Action OnButtonClicked;
Then hook the button clicked event from the designer
private void btn_myButton_Clicked(object sender, EventArgs e)
{
if (OnButtonClicked != null)
OnButtonClicked();
}
Then in your parent container, you want to handle this event from the child control
this.myChildControl.OnButtonClicked += new Action(onChildButtonClicked);
private void onChildButtonClicked()
{
// Do your search here
}

Related

Custom UserControl's click event does not fire

So I created a custom UserControl just out of a PictureBox and a RadioButton, something like the following:
public partial class Foo : UserControl
{
//some declared properties for the designer...
}
Now I added this object to a Form and subscribed to it's Click() event.
private void customAddedContr_Click(object sender, EventArgs e) { }
But just clicking on this red marked part fires the Click() event.
So just by clicking on the UserControl itself, so when a click is performed on the PictureBox or RadioButton this Click() event does not get fired. I thought that the Click event for this new UserControl gets fired for each click aiming to this Window Handle.
So do I need to bind the PictureBox's and RadioButton's Click() event to the UserControl's Click() event earlier on or what do I oversee?
Edit:
For understanding purpose, here is a colored picture of the CustomControl.
The top dark grey part is the PictureBox. The blue one is the UserControl itself on which I placed the other controls. The light grey bottom is the RadioButton. So just clicking on the blue part (UserControl) fires the Click() event.
I would recommend exposing the picturebox and radio buttons click events separately.
You raise your own events for the radio and picturebox at the usercontrol level and inside each click even you would raise the controls events. then you handle those click events outside the control and respond accordingly.
public partial class Foo : UserControl
{
public event EventHandler RadioButtonClicked;
public event EventHandler PictureBoxClicked:
}
then in the picturebox or button click event inside the control you raise the individual event at the control level
private void PictureBox1_Click(object sender, EventArgs e)
{
if (PictureBoxClicked != null)
PictureBoxClicked(sender, e);
}

binding custom control to an external button

I have a custom control that i'm using in an external application. I want to bind a click event of a random button in the application to add data to my control.
Is something like that even possible?? Basically what i was thinking was creating a property in my control that allows a developer to add a button control to it at design time. And then when the application is run, any clicks registered on the button will be forwarded to a method in the custom control to add data.
Is this doable? if so, can someone explain what needs to be done exactly?
You can create a property of type Button in your custom control. Then when you put an instance of custom control on the designer, for that property, you will see a dropdown that shows all Button instances on the form which you can select one of them. It's enough to add a method to click event of the button in setter of the property:
using System;
using System.Windows.Forms;
public class MyControl : UserControl
{
private Button addButton;
public Button AddButton
{
get { return addButton; }
set
{
if (addButton != null)
addButton.Click -= new EventHandler(addButton_Click);
addButton = value;
if (addButton != null)
addButton.Click += new EventHandler(addButton_Click);
}
}
void addButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Add Button Clicked!");
}
}
When you put it on designer, for AddButton property, a list o available buttons on the form will be shown. it's enough to choose one of them, then the behavior which you want (here in the example, showing the message box) will attach to click event of that button.

C# click on control

I'm trying to create a custom control which fires an even on click.
My control is just a panel with a couple of labels and a picturebox inside.
The click works perfectly, the only issue is that I have to click the background of the control and if I press on the picturebox, is not working.
I've added the on click event to the control, but I would like to press in every place of it to trigger the event, not just the background of the panel.
I thought about adding a transparent object that covers entirely the control. I actually don't like this idea, however, I've tried with a picturebox, but i cannot see through it. It's not transparent. I can just see the panel background but It covers the labels and the image.
Thanks for the support.
If you just have a couple of objects in your panel, you can hook the Click event of all objects it contains to the same event handler, there is nothing wrong doing this.
public class MyUserControl : UserControl
{
public event Action<MyUserControl> MyControlClick
public string ID {get; set;}
public MyUserControl()
{
InitializeComponents();
// The same event handler code will be used for the three controls
myPictureBox.Click += global_Click;
myLabel1.Click += global_Click;
myLabel2.Click += global_Click;
this.Click += global_Click;
}
void global_Click(object sender, EventArgs e)
{
if (MyControlClick != null)
MyControlClick(this);
}
}
If you have a more important amount of objects, you can rely on this answer to create a truly transparent panel that handles clicks. The drawback is that you will have to detect which object has been clicked by using HitTest based on the mouse location.
On the form side :
aControl.MyControlClick += aControl_MyControlClick;
// ...
// This code is triggered when a MyUserControl is clicked
void aControl_MyControlClick(MyUserControl ctl)
{
MessageBox.Show(ctl.ID);
}
Actually! You cannot raise any event to the element in the Usercontrol unless you have to apply own method to your usercontrol or you can disable the element in the usercontrol but it will change the color of that element but It will raise the click event when you click your control.

Windows Forms - detecting button click from a panel inside the form

I have Windows Form named - Form1 and inside Form1 I have a panel named panel1. I use this panel only to add buttons in him. For now there are exactly 9 buttons but I intend to change their number dynamicly if this has something to do with my current problem. What I need is way to detect a when a button from this panel is clicked (I have other buttons too but, they are in Form1 outside the panel) and also to know exactly which button was clicked.
I tried this:
private void panel1_Click(object sender, EventArgs e)
{
MessageBox.Show("HI" + sender);
}
As you can see, it's not much, but was enough to see that I can't do that using pnael1's_click event. Using this code I get the message box when I click anywhere in the panel except the buttons. So how can I do that. Is it possible to do it from inside panel1 or I should group those buttons using another approach but it's important to be able to keep the difference between those buttons which are now in panel1 and the other buttons I may (and in in fact I do have)?
When creating the dynamic buttons, you register that button instance's Click event and attach to an event handler (a single handler can handle all buttons' click event):
var dynamicButton1 = new Button();
dynamicButton1.Click += MyButtonClickHandler;
As long as MyButtonClickHandler has a signature that's suitable for a Click event (that's any method returning void and taking an object and an EventArgs, the handler should respond to a dynamic button's click event for as long as the button instance exists.
As long as you aren't adding controls dynamically over time, and the number of buttons is fixed as soon as the form is initialized, you can use this to add a click event handler to all buttons within a panel:
foreach (var button in panel.Controls.OfType<Button>())
{
button.Click += HandleClick;
}

.NET UserControl accept button best practice?

I have a windows forms app where I have split different functionality into several user controls. I want each of these user controls to have an accept button.
Any best practices here?
My idèa is to detect which user control that has focus, and than set it in the parent Form.
Any other idèas?
The best practice is usually to only have one accept button for your form so that its behavior is consistent. It generally would be confusing for users if hitting return caused different actions depending on which section of the form had focus. However, if you have a specialized application or users have requested this feature then I think the solution you propose would work.
Jan Miksovsky has an excellent blog on UI design, and wrote an article about this very thing.
Most UI platforms allow a designer to
indicate which button in a dialog
should be the default button: the
button that will be pressed if the
user types the Enter key. The default
button is generally the button the
user is most likely to press next,
often a button like OK that closes the
dialog. In very high-traffic dialogs,
you may want to consider dynamically
changing the default button to save
keystrokes and help speed the user's
task.
The example he uses is the "Select Names" dialog in Microsoft Outlook, which changes the default button depending on what you are doing.
I assume each user button is its own instance on the individual user controls?
If so then you can trap the button events on the Parent form. If you expose the individual buttons through a property you can tie into their Click events. Like all controls they have a name property so you can have one method that is called on all button click events.
Below I have a partial sample code. I have two user controls that have one button each. The button on UC1 is named "btn1" and "btn2" for UC2. I call the exposed property "ButtonOK"
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public Button ButtonOK
{
get { return btn1; }
}
}
public partial class UserControl2 : UserControl
{
public UserControl2()
{
InitializeComponent();
}
public Button ButtonOK
{
get { return btn2; }
}
}
Now on the parent ("Form1") when it loads have a mthod that ties into the Click events of each button but it calls the same method. Inside the method I test for the "Name" property.
public Form1()
{
InitializeComponent();
}
void Form1_Load(object sender, EventArgs e)
{
RegisterButtonEvents();
}
void RegisterButtonEvents()
{
userControl11.ButtonOK.Click += new EventHandler(ButtonOK_Click);
userControl21.ButtonOK.Click += new EventHandler(ButtonOK_Click);
}
void ButtonOK_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
if (btn != null)
{
if (btn.Name == "btn1")
{
Console.WriteLine(" ButtonOK from UserControl1 was pushed. The tag is " + btn.Tag.ToString());
}
else if (btn.Name == "btn2")
{
Console.WriteLine(" ButtonOK from UserControl2 was pushed. The tag is " + btn.Tag.ToString());
}
}
}
You can also user the "Tag" property of a control. This property can be very useful as it can reference objects.
You don't need to do exactly as shown but you can use any "Parent" form to get a reference to the UserControls, have them expose their Buttons, then you can do anything you want with properties and events from those Buttons (or any control for that matter).
Keep in mind that if you are tying into the click event on the user control also (in addition to the parent form), you will have to be mindful of the order in which it will enumerate through it list of delegates and execute code after the event is intiated.
Hope that helps.
I know this is an old post, but I think I figured it out.
Use the "Enter" event on each user control from the main form, such that when the user "enters" (focuses on) the user control, this.AcceptButton = myUserControlButton. You can also use the "Leave" event on each user control to set the accept button back to the default, if you have one.
I'm not sure if I understood your question correctly.
If you want to assign one event to several buttons:
For this you could for instance:
- Get the button name on the Button_Click event.
- Enumerate between names
- Iterate over the controls.
Example bellow:
"How to get the button name from the Button_Click event".
// First; dont forget to assign the "Button_Click" event to your Button(s).
private void Button_Click(object sender, EventArgs e)
{
// The line bellow assigns to "btn" variable the currently clicked button.
Button btn = (Button)sender;
// Then using a switch block; you can compare the button name and
// perform the action desired for the clicked button.
switch(btn.Name)
{
case "buttonName1": /* Do Something Here */ break;
case "buttonName2": /* Do Something Here */ break;
// etc
}
}
Additionally; if you require; there's always the way to retrieve the Button outside the form class by exposing them.

Categories

Resources