I have a loop that could create 1 or maybe 10 or maybe 584575 (example, not actually true) FlowLayoutPanels. For all these panels I want a hover event handler, or maybe later another type of event handler but for now only hover.
How can I make this happen for multiple same type created controls?
FlowLayoutPanel finalResult_panel = new FlowLayoutPanel{
FlowDirection = FlowDirection.LeftToRight,
BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle,
Name = "result_flowLayoutPanel" + i,
Size = new System.Drawing.Size(790, 72),
TabIndex = i,
};
You can attach the handler like this
finalResult_panel.MouseHover += panel_MouseHover;
private void panel_MouseHover(object sender, EventArgs e)
{
}
Alternatively you can create an anonymous delegate
finalResult_panel_MouseHover += (s,e) => {
//event code
};
These will attach the same handlers to every panel so if you need to differentiate, you can do that in the handler itself (using the sender property) or somehow differentiate before attaching the handler.
Related
I have a problem with User form Click that I am trying to make in C# using a usercontrol.
It consists of a picturebox and a label. I want to call the click event but the picturebox and the label don't do anything when I click them. Only the background area of the usercontrol does what I want it to do. Any ideas?
here's my code
for (int i = 0; i < listitems2.Length; i++)
{
listitems2[i] = new declined();
//adding sample data to each dynamic user
listitems2[i].dicon = dicon[i];
listitems2[i].did = did[i];
listitems2[i].dname = dname[i];
//adding data to flow layout panel
flowLayoutPanel2.Controls.Add(listitems2[i]);
// below line will assing this (usercontrolclick) event to every user control created dynamically
listitems2[i].Click += new System.EventHandler(this.UserControl_Click);
}
for click function
void UserControl_Click(object sender, EventArgs e)
{
string ctrlName = ((UserControl)sender).Name;
applicable obj = (applicable)sender;
studid.Text = obj.id;
studname.Text = obj.name;
pictureBox1.Image = obj.icon;
}
You added OnClick handler to your UserControl, so only clicks made on UserControl will be registered. To enable Click event for all the controls on your form, you need to add your click handler to all other controls.
But, according to your code, you're adding click handling on form where your control is located. In this case, you cannot register clicks on control from "outside" (you can by making Label and PictureBox controls public and adding handlers for their OnClick events but that is wrong way to do it)
My suggestion is to make custom event on your form and raise it on Form, Label and PictureBox click, and then make handler for that event on form which holds your UserControl.
Something like this:
//make custom eventHandler on your UserControl
[Browsable(true)]
public event EventHandler UserControlClicked;
//constructor
public UserControl1()
{
InitializeComponent();
//after intialize compoment add same handler for all three controls
this.Click += ControlClicked;
this.pictureBox1.Click += ControlClicked;
this.label1.Click += ControlClicked;
}
//this method will "catch" all clicks
private void ControlClicked(object sender, EventArgs e)
{
//raise event
UserControlClicked?.Invoke(this, e);
}
and on form where your custom control is, add handler for UserControlClicked (maybe with cast, I don't know what listItems2[i] contains):
listitems2[i].UserControlClicked+= new System.EventHandler(this.UserControl_Click);
or maybe like this (with casting)
(listitems2[i] as UserControl1).UserControlClicked+= new System.EventHandler(this.UserControl_Click);
and handle the rest in your UserControl_Click method like before
I am attempting to learn c# and wpf. I have a segment of code that works in that it shows the controls correctly. I also attempt to create a mouse button handler and when I debug it, the handler is never called. The buttons are nested within a couple of StackPanels, that can't seem to be the problem?
StackPanel tabPanel = new StackPanel();
for (int i = 0; i < 20; i++)
{
StackPanel micPanel = new StackPanel();
micPanel.Orientation = Orientation.Horizontal;
// Add the Calibration Button
Button micButton = new Button();
micButton.Height = 25;
micButton.Name = string.Format("Mic{0}", i);
micButton.Content = string.Format("Mic{0}", ((20 * index) + i));
micButton.MouseLeftButtonUp += new MouseButtonEventHandler(mic_MouseLeftButtonUp);
micPanel.Children.Add(micButton);
// Add the calibrated Value
Label micLabel = new Label();
micLabel.Height = 25;
micLabel.Content = string.Format("Value: {0}", ((20 * index) + i));
micPanel.Children.Add(micLabel);
tabPanel.Children.Add(micPanel);
}
tab.Content = tabPanel;
The handler looks like this:
private void mic_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Button but = sender as Button;
}
I set a breakpoint and it never calls the handler?
This is typical: use the preview event handler to make sure it is raised first in the tree view.
micButton.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(mic_MouseLeftButtonUp);
Why don't you handle the Click event of the Button?
micButton.Click += new ClickEventHandler(mic_Click);
...
private void mic_Click(object sender, RoutedEventArgs e)
{
Button but = sender as Button;
}
Certain controls do "swallow" certain events but the Button control doesn't raise any MouseButtonUp event. It raises a Click event. The Click event is actually a combination of the LeftButtonDown and LeftButtonUp event:
WPF MouseLeftButtonUp Not Firing
You can read more about routed events and how they work in the documentation on MSDN: https://msdn.microsoft.com/en-us/library/ms742806%28v=vs.110%29.aspx
In Windows Forms project I have this method to set some properties of dynamically created control. In this case I also need to show a tooltip when user hovers mouse over it. This works ok except for one thing, I have no idea how to pass the value of w["text"] to control_MouseEnter.
private void SetProp(ref Control obiekt, Dictionary<string, string> w)
{
obiekt.Name = w["id"];
obiekt.Location = new Point(Convert.ToInt16(w["wspx"]), Convert.ToInt16(w["wspy"]));
obiekt.Height = Convert.ToInt16(w["wys"]);
obiekt.Width = Convert.ToInt16(w["szer"]);
if (w["text"] != "")
{
obiekt.MouseEnter += new EventHandler(control_MouseEnter);
obiekt.MouseLeave += new EventHandler(control_MoouseLeave);
}
}
private void control_MouseEnter(object sender, EventArgs e)
{
toolTip.Show("how to pass a value here ??", (Control)sender, 5000);
}
I have no idea has to pass the value of w["text"] to control_MouseEnter.
You can either link your data with target control directly (for example via Control.Tag property) or indirectly (for example, via global variable/dictionary), or use anonymous delegate and closure to create the local data-context:
obiekt.MouseEnter += (s,e) => {
tooltip.Show(w["text"], (Control)s, 5000);
};
Is there a way to use EventArgs somehow?
No, you can't. Because the args are instantiated within the Control's code exactly at the moment when the mouse event occurs, and you can't control the EventArgs creation from event-subscription point.
How about setting the text into Tag member of Control object?
S.th. like object.Tag = w["text"]; and show it with event handler
Hi I want to add several buttons and their click events dynamically to my windows forms application in my code behind where my buttons will execute System.Diagnostics.Process.Start(targetURL); how can I acheieve this ?
You just need to create the button, set it's properties and event handlers and then add it to the Controls collection on the form.
var button = new Button();
try
{
button.Text = "Button 1";
button.Click += (sender, e) => System.Diagnostics.Process.Start(targetURL);
//Or if you don't want to use a lambda and would rather have a method;
//button.Click += MyButton_Click;
Controls.Add(button);
}
catch
{
button.Dispose();
throw;
}
//Only needed when not using a lambda;
void MyButton_Click(Object sender, EventArgs e)
{
System.Diagnostics.Process.Start(targetURL);
}
Declare your buttons variables.
Add the event handlers
Add them to the form Controls property.
Profit
You can add any control you like to the Controls collection of the form:
var targetURL = // ...
try
{
SuspendLayout();
for (int i = 0; i < 10; i++)
{
var button = new Button();
button.Text = String.Format("Button {0}", i);
button.Location = new Point(0, i * 25);
button.Click += (object sender, EventArgs e) => System.Diagnostics.Process.Start(targetURL);
this.Controls.Add(button);
}
}
finally
{
ResumeLayout();
}
When adding several controls to a parent control, it is recommended that you call the SuspendLayout method before initializing the controls to be added. After adding the controls to the parent control, call the ResumeLayout method. Doing so will increase the performance of applications with many controls.
You could write a user control that contains a textbox "txbURL", a button "btnNavigateToURL" and write the eventhandler of your button, to execute your code (System.Diagnostics.Process.Start(targetURL);)
Once you've done that, it's easy to add your control to your form on runtime, writing some code like this (don't have a c# editor right now, so you may have to verify the code)
MyControlClassName userControl = new MyControlClassName(string targetUrl);
userControl.Parent = yourForm;
yourForm.Controls.Add(userControl);
that's it.
I am currently using the code in main.cs to draw out the GUI instead of using the [design] form. I understand that if you are using the [design] file to draw your GUI, all you have to do to create a event handler is just to double click the object.
But since I am using the code the draw out the labels/buttons, how do I do a event handler for that particular button/object?
p.Controls.Add(new Button
{
Text = "Clear",
Name = "btnClear",
Location = new Point(416, 17)
});
e.g. how do I add an event handler for the above code?c
You need to first create an instance of your button and assign it to a variable. Then you can add an event handler by calling += on the Click event of the button.
// This is a method body
{
Button btnClear = new Button
{
Text = "Clear",
Name = "btnClear",
Location = new Point(416, 17)
};
p.Controls.Add(btnClear);
btnClear.Click += new EventHandler(btnClear_Click);
}
void btnClear_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
In Visual Studio, after typing btnClear.Click += you can just press Tab twice and it will add the rest of the code.