How determine which control was clicked in WPF UserControl? - c#

I have a WPF user contol, in which I have a StackPanel. To this panel I'm adding programatically a label this way (Container is the name of StackPanel):
public void Insert(string Value)
{
Label l = new Label();
l.Content = Value;
Container.Children.Add(l);
}
Now I want to provide some public event SelectedIndexChange, when user clicks on label. Now I have a problem how determine which label was clicked. Can someone help?

If in Insert you add the line:
l.Click += ClickHandler;
then the first argument of ClickHandler will be the control that raised the Click event.
e.g. If your handler is:
private void ClickHandler(object sender, RoutedEventArgs e){...};
then sender will be the label that was clicked.
You could alternatively look at e.OriginalSource.

I Guess You Can Use This Code
l.MouseClick+= MouseClickHandler;
And Switch Between Lables
Example:
private void label1_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton== MouseButtonState.Pressed)
{
Label l = (Label)e.Source;
switch (l.Name)
{
case "lable1":
int a = 10;
break;
}
}
}

Related

C# assign an event to a "group" of controls?

I have a big numbers of labels custom controls let's say 100.
I would like to give them an MouseHover event.
I could do something like:
private void label_custom1_MouseHover(object sender, EventArgs e)
{
TextBox.Text = label_custom1.backcolor.ToString();
}
But then I would need to do that 100 times. Since I have 100 of them.
Is there a way to do that only once?
I guess I should probably declare the function in my custom_label class but so far I couldn't make it work.
Any Idea how to proceed?
Create only one event handler method like this:
private void Label_MouseHover(object sender, EventArgs e)
{
TextBox.Text = (sender as Label).BackColor.ToString();
}
And subscribe all Events to that method:
this.label_custom1.MouseHover += Label_MouseHover;
this.label_custom2.MouseHover += Label_MouseHover;
Thank you, this was very helpful.
This part didnt work though, it couldnt recognize the controls:
private void SetEventAllLabels()
{
var labels = Controls.OfType<Label>().Where(x => x.Name.StartsWith("label"));
foreach (var label in labels)
{
label.MouseHover += Common_MouseHover;
}
}
So I create a list containing all the label names and Then it works using this:
foreach (string i in liste)
{
CustomLabel x = (CustomLabel)(this.Controls.Find(i, true).FirstOrDefault() as Label);
x.MouseEnter += Common_MouseHover;
}
As a side note, using MouseEnter instead of MouseHover makes it much more responsive (faster reaction!)
Firstly, create a common event, we receive the Label posted here.
private void Common_MouseHover(object sender, EventArgs e)
{
TextBox.Text = (sender as Label).BackColor.ToString();
}
Give the common event to all Labels on the form. Here I assume Label names start with label, for example label1, label2, label3 ...
private void SetEventAllLabels()
{
var labels = Controls.OfType<Label>().Where(x => x.Name.StartsWith("label"));
foreach (var label in labels)
{
label.MouseHover += Common_MouseHover;
}
}
Call the SetEventAllLabels () method in the Load method of the form.
private void Form1_Load(object sender, EventArgs e)
{
SetEventAllLabels();
}

Generic MouseButtonEventHandler for TextBox and Label

Learning WPF with MacDonald's "Pro WPF 4.5 in C#," focusing on Ch5, Events.
How would I write a generic event handler that works with both Labels and TextBoxes to process the MouseDown event initializing a drag & drop procedure?
Here is my TextBox handler:
private void tBSource_MouseDown(object sender, EventArgs e) {
TextBox tBox = (TextBox)sender;
DragDrop.DoDragDrop(tBox, tBox.Text, DragDropEffects.Copy);
}
And my Label handler:
private void lblSource_MouseDown(object sender, EventArgs e) {
Label lbl = (Label)sender;
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Copy);
}
As you can see, I'm using the Content property and the Text property, depending on which object starts the event. If I try to use the same property for both senders, I get build errors (regardless of which I use). If I can avoid duplication, I would be very happy. Should I chunk a conditional out into another function and call that in the handler to determine what property should be used?
you could do something like this:
private void Generic_MouseDown(object sender, EventArgs e)
{
object contentDrop = string.Empty;
//Label inherits from ContentControl so it doesn't require more work to make work for all controls inheriting from ContentControl
if (sender is ContentControl contentControl)
{
//If you don't want to filter other content than string, you can remove this check you make contentDrop an object
if (contentControl.Content is string)
{
contentDrop = contentControl.Content.ToString();
}
else
{
//Content is not a string (there is probably another control inside)
}
}
else if (sender is TextBox textBox)
{
contentDrop = textBox.Text;
}
else
{
throw new NotImplementedException("The only supported controls for this event are ContentControl or TextBox");
}
DragDrop.DoDragDrop((DependencyObject)sender, contentDrop, DragDropEffects.Copy);
}
Let me know if you have any question

Detect SplitContainer's select Panel

I have Windows Form named Form1 and inside I have a dynamic SplitContainer named splitcontainer.
I want to know which panel is selected when the mouse is clicked at runtime.
I tried to use mouseclick event in the splitContainer properties but I haven't succeed.
You need to bind to the MouseClick events of the panel inside the split container.
I added a container called "splitContainer1" with 2 panels, Panel1 and 2
I wired up the below events and it seems to work
private void splitContainer1_Panel1_MouseClick(object sender, MouseEventArgs e)
{
MessageBox.Show("Panel1");
}
private void splitContainer1_Panel2_MouseClick(object sender, MouseEventArgs e)
{
MessageBox.Show("Panel2");
}
After your further comments, I've edited the below to show how to manually bind the mouse click events of the 2 panels of your dynamically added container.
private void splitContainerHorizontalToolStripMenuItem_Click(object sender, EventArgs e)
{
SplitContainer spltcnt = new SplitContainer();
spltcnt.Dock = DockStyle.Left;
spltcnt.Orientation = Orientation.Horizontal;
spltcnt.SplitterWidth = 4;
spltcnt.Visible = true;
spltcnt.Size = new System.Drawing.Size(731, 615);
spltcnt.BorderStyle = BorderStyle.Fixed3D;
spltcnt.SplitterDistance = 351;
//Manually bind the mouse click events.
spltcnt.Panel1.MouseClick += Panel1OnMouseClick;
spltcnt.Panel2.MouseClick += Panel2OnMouseClick;
Controls.Add(spltcnt);
}
private void Panel1OnMouseClick(object sender, MouseEventArgs mouseEventArgs)
{
MessageBox.Show("Panel1");
}
private void Panel2OnMouseClick(object sender, MouseEventArgs mouseEventArgs)
{
MessageBox.Show("Panel2");
}
You can of course call the mouse click handler methods anything you like.
Thanks

Getting access to Button parent

I'm using a Button in a class. When the button is pressed, it should call a routine with the button's corresponding text. How do I convert the sender into a String_Entry? Also, I'm quite a newbie regarding object oriented/class programming, so comments are welcome.
public class String_Entry
{
public TextBox textbox;
public Button send;
// other stuff
public String_Entry()
{
textbox = new TextBox();
send = new Button();
send.Click += new System.EventHandler(this.bSend_Click);
// put in GUI, set parameters and other stuff
}
// other stuff
private void bSend_Click(object sender, EventArgs e)
{
// Trying to get the corresponding String_Entry from the Button click event
Button cntrl = (Button)sender;
String_Entry entry = (String_Entry)(cntrl.Parent);
parse.ProcessHexLine(entry);
}
}
Your solution of encapsulating a button with a textbox and the event handler is sound. It just goes wrong in the event handler:
private void bSend_Click(object sender, EventArgs e)
{
Button cntrl = (Button)sender;
String_Entry entry = (String_Entry)(cntrl.Parent);
parse.ProcessHexLine(entry);
}
Firstly, there is no point to doing anything with sender as it'll be the same as the field send. Next cntrl.Parent will give you a reference to the Form, or other container object, that contains the button, not this instance of String_Entry. To access that, use this. So you can change the event handler to:
private void bSend_Click(object sender, EventArgs e)
{
parse.ProcessHexLine(this);
}

Preserve control's visibility on condition

This is probably an easy one for some of you.
I have a TextBox and a ListBox. ListBox provides options for the TextBox and copies selected item's text to TextBox on DoubleClick event. ListBox becomes visible only when TextBox fires Enter event. I do not want to discuss my reasons for selecting this control combination.
I want ListBox to disappear when any other control within the Form gets focus. So I capture Leave event of TextBox and call ListBox.Visible = fale The problem is that TextBox will also loose focus when I click on ListBox to select provided option thus preventing me from selecting that option.
What event combination should I use to preserve ListBox to select option but hide it whenever other controls get focus?
In the Leave method, you can check to see if the ListBox is the focused control or not before changing its Visibility:
private void myTextBox_Leave(object sender, EventArgs e)
{
if (!myListBox.Focused)
{
myListBox.Visible = false;
}
}
This example will provide you with the desired outcome:
public Form1()
{
InitializeComponent();
textBox1.LostFocus += new EventHandler(textBox1_LostFocus);
textBox1.GotFocus += new EventHandler(textBox1_GotFocus);
}
void textBox1_GotFocus(object sender, EventArgs e)
{
listBox1.Visible = true;
}
void textBox1_LostFocus(object sender, EventArgs e)
{
if(!listBox1.Focused)
listBox1.Visible = false;
}
private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
textBox1.Text = listBox1.SelectedItem.ToString();
}
private void Form1_Shown(object sender, EventArgs e)
{
//if your textbox as focus when the form shows
//this is the place to switch focus to another control
listBox1.Visible = false;
}

Categories