I made a method what adds a TextBox to a Grid, but when i set it to focus it just won't.
This is the code what makes the textBox, and adds to the grid:
public static TextBox TextEditor(this FrameworkElement obj, Grid parent)
{
Label text = obj as Label;
TextBox edit = new TextBox();
edit.Text = text.Content.ToString();
edit.VerticalContentAlignment = VerticalAlignment.Center;
edit.Margin = obj.Margin;
edit.SetSize(obj);
edit.HorizontalAlignment = HorizontalAlignment.Left;
edit.VerticalAlignment = VerticalAlignment.Stretch;
edit.FontSize = 15;
parent.Children.Add(edit);
edit.KeyDown += (s, e) =>
{
if(e.Key == Key.Enter)
{
text.Content = edit.Text;
parent.Children.Remove(edit);
}
if(e.Key == Key.Escape)
{
parent.Children.Remove(edit);
}
};
parent.SizeChanged += (s, e) =>
{
edit.SetSize(obj);
};
edit.Focusable = true;
return edit;
}
Here the code what calls the TextEditor method and set the textbox in focus, or at least tries it:
private void Type_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
Type.TextEditor(PreviewItems).Focus();
}
The Type variable is a Label. I searched a lot but couldn't find a solution. Why doesn't it work?
I tried every method in this post:
WPF: Can't get my control to take focus
Related
I have a combobox "recent_users" as a control template and then as a poppup. How can I pass the selected value of the popup to the method below?(popup click)
recent_users.SelectedItem.ToString() always returns null.
private void usernameEnter_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
Trace.WriteLine("testing dropdown");
ControlTemplate ct = recent_users.Template;
Popup popup1 = ct.FindName("PART_Popup", recent_users) as Popup;
if (popup1 != null)
{
popup1.Placement = PlacementMode.Top;
}
recent_users.IsDropDownOpen = true;
popup1.PreviewMouseUp += new MouseButtonEventHandler((s,e) => popupClick(s,e,recent_users.SelectedItem.ToString()));
}
private void popupClick(object sender, MouseButtonEventArgs e, String recent)
{
usernameEnter.Text = recent;
Trace.WriteLine("appending norms");
}
}
}
Isn't it because the user has not made any selection in the ComboBox? I have re-written the code slightly
private void usernameEnter_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
ControlTemplate ct = recent_users.Template;
Popup popup1 = ct.FindName("PART_Popup", recent_users) as Popup;
if (popup1 != null)
{
popup1.Placement = PlacementMode.Top;
}
recent_users.IsDropDownOpen = true;
// if none selected, set first as selected
if (recent_users.SelectedIndex < 0 && recent_users.HasItems)
{
recent_users.SelectedIndex = 0;
}
var selectedItem = recent_users.SelectedItem as ComboBoxItem;
var selectedUser = selectedItem.Content.ToString();
popup1.PreviewMouseUp += new MouseButtonEventHandler((s, e) => popupClick(s, e, selectedUser));
}
But I was wondering adding a handler for PreviewMouseUp event (in the last line) is something that you really want. I would have fetched the selected user in the SelectionChanged of the recent_users rather.
This question already has answers here:
Apply same event to every project button in a C#
(2 answers)
Closed 3 years ago.
I want to add click,mouseleave and mouseenter event to all labels in the form using code below. But i call the addeventtoalllabels on form_load but it wont add event to labels.
public void setColor()
{
if (clickedLabel != default(Label))
clickedLabel.BackColor = Color.Yellow;
//Resetting clicked label because another (or the same) was just clicked.
}
void addeventtoalllabels()
{
foreach (Label c in this.Controls.OfType<Label>())
{
try
{
c.Click += (sender, e) => {
setColor();
Label theLabel = (Label)sender;
clickedLabel = theLabel;
};
c.MouseEnter += (sender, e) =>
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel)
theLabel.BackColor = Color.Red;
};
c.MouseLeave += (sender, e) =>
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel)
theLabel.BackColor = Color.Yellow;
};
}
catch { }
}
}
It sounds like the problem is that some of your labels are inside other container controls, so they aren't getting iterated over when you do this.Controls.OfType<Label>() (all Control objects have a Controls collection).
One way to work around this is to recursively look through all the controls' Controls collections so you can find the child Label objects that belong to other container controls.
Below are 3 methods:
AddEventsToLabel takes in a Label control and adds events to it.
AddEventsToChildLabels takes in a Control argument and checks to see if it's a Label. If it is, it passes it to the method in #1 above. Otherwise, it recursively calls itself for each child control of the one that was passed in.
AddEventsToAllLabels is used to kick off the process - this method calls the method in #2 above, passing in the Form itself as the parent control (this).
This way we end up iterating over every control on the form, including all those inside other container controls:
private void AddEventsToAllLabels()
{
AddEventsToChildLabels(this);
}
private void AddEventsToChildLabels(Control parent)
{
if (parent is Label)
{
AddEventsToLabel(parent as Label);
}
else
{
foreach (Control control in parent.Controls)
{
AddEventsToChildLabels(control);
}
}
}
private void AddEventsToLabel(Label label)
{
label.Click += (sender, e) => {
SetColor();
Label theLabel = (Label)sender;
clickedLabel = theLabel;
};
label.MouseEnter += (sender, e) =>
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel) theLabel.BackColor = Color.Red;
};
label.MouseLeave += (sender, e) =>
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel) theLabel.BackColor = Color.Yellow;
};
}
Note that it might be better to first remove the event handler before adding it, in case this method gets called more than once. Otherwise, if you hook the same event hander to the same event more than once, each time that event is raised, the handler will execute the number of times that it was added.
For example:
private void AddEventsToLabel(Label label)
{
label.Click -= LabelClick;
label.MouseEnter -= LabelMouseEnter;
label.MouseLeave -= LabelMouseLeave;
label.Click += LabelClick;
label.MouseEnter += LabelMouseEnter;
label.MouseLeave += LabelMouseLeave;
}
private void LabelClick(object sender, EventArgs e)
{
SetColor();
Label theLabel = (Label)sender;
clickedLabel = theLabel;
}
private void LabelMouseEnter(object sender, EventArgs e)
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel) theLabel.BackColor = Color.Red;
}
private void LabelMouseLeave(object sender, EventArgs e)
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel) theLabel.BackColor = Color.Yellow;
}
I have a custom TextBox control defined as follows:
class PHTextBox : System.Windows.Forms.TextBox
{
System.Drawing.Color DefaultColor;
public string PlaceHolderText { get; set; }
public PHTextBox(string placeholdertext)
{
// get default color of text
DefaultColor = this.ForeColor;
// Add event handler for when the control gets focus
this.GotFocus += (object sender, EventArgs e) =>
{
this.Text = String.Empty;
this.ForeColor = DefaultColor;
};
// add event handling when focus is lost
this.LostFocus += (Object sender, EventArgs e) => {
if (String.IsNullOrEmpty(this.Text) || this.Text == PlaceHolderText)
{
this.ForeColor = System.Drawing.Color.Gray;
this.Text = PlaceHolderText;
}
else
{
this.ForeColor = DefaultColor;
}
};
if (!string.IsNullOrEmpty(placeholdertext))
{
// change style
this.ForeColor = System.Drawing.Color.Gray;
// Add text
PlaceHolderText = placeholdertext;
this.Text = placeholdertext;
}
}
}
I am trying to add a custom textBox in the following way to a Panel:
this.tbNombresClienteConfirmarPago = new PHTextBox("Your name");
this.tbNombresClienteConfirmarPago.Location = new System.Drawing.Point(0,0);//(644, 485);
this.tbNombresClienteConfirmarPago.Name = "tbNombresClienteConfirmarPago";
this.tbNombresClienteConfirmarPago.Size = new System.Drawing.Size(203, 20);
this.tbNombresClienteConfirmarPago.TabIndex = 7;
this.tbNombresClienteConfirmarPago.MaxLength = 50;
this.panel1.Controls.Add(this.tbNombresClienteConfirmarPago);
But it does not work.
I add a textBox or a button that belong to Windows Forms and they are added correctly to the Panel without problems.
Any comment is welcomed.
Upgrade:
When I wanted to say that 'It doesn't work' I was referring to the fact that the object is not displayed inside the Panel.
A PHTextBox is displayed correctly within the form.
My code makes 5 labels appear with a random .Left location, you can see it.
I want the particular label to disappear when I click on it, but I don't know how to tell it to my click void.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Label [] kubeliai = new Label [5];
int poz = 100;
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < kubeliai.Length; i++)
{
kubeliai[i] = new Label();
Controls.Add(kubeliai[i]);
Random pos = new Random();
kubeliai[i].Top = 50;
kubeliai[i].Left = poz;
poz += pos.Next(50, 200);
kubeliai[i].BackColor = Color.Red;
kubeliai[i].Height = 20;
kubeliai[i].Width = 20;
kubeliai[i].Click += new EventHandler(kubelio_clickas);
}
}
void kubelio_clickas (object sender, EventArgs e)
{
}
}
The instance of "clicked" label is in sender parameter:
void kubelio_clickas (object sender, EventArgs e)
{
Label clickedLabel = sender as Label;
if (clickedLabel != null) {
clickedLabel.Visible = false;
}
}
Because in .NET Event Handlers by default use object as type of sender you have to cast it to Label first.
I want the particular label to disappear when I click on it
Just set the label's .Visible property to false:
void kubelio_clickas (object sender, EventArgs e)
{
if (sender is Label)
((Label)sender).Visible = false;
}
The object sender is a reference to the object which fired the event. So basically, the sender is the object you are looking for.
You just need to set it invisible:
((Label)sender).Visible = false;
I programmatically create a Form with two textboxes. My goal is to disable one textbox if I type something in the second one and contrariwise. I managed to disable second textbox on first textbox textchange,but can't figure out how enable it when the first textbox.Text is empty.
Here is the code :
private void metaName_TextChanged(object sender,EventArgs e)
{
var ctrl = (Control)sender;
var frm = ctrl.FindForm();
TextBox metaTxt = null;
foreach (var ctr in frm.Controls)
{
if (ctr is TextBox)
{
metaTxt = (TextBox)ctr;
if (metaTxt.Name == "metaHTTPEquiv")
{
metaTxt.Enabled = false;
}
else
if (?)
{
}
}
}
}
I want to make something like this :
if(textBox3.Text == String.Empty)
{
textBox4.Enabled = true;
}
else
if(textBox3.Text != String.Empty)
{
textBox4.Enabled = false;
}
You can check only the textchanged event for each one like the following:
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox2.Enabled = !(textBox1.Text.Length >= 1);
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
textBox1.Enabled = !(textBox2.Text.Length >= 1);
}
The self textbox has some values, then the enabled will be false for the other one
First set a flag to enable or disable the second control based on the content of the metaName textbox that raises the event, then search for the second textbox using a bit of Linq.
private void metaName_TextChanged(object sender,EventArgs e)
{
TextBox ctrl = sender as TextBox;
if(ctrl != null)
{
bool enable = !string.IsNullOrEmpty(ctrl.Text);
TextBox secondOne = this.Controls
.OfType<TextBox>()
.FirstOrDefault(x => x.Name == "metaHTTPEquiv");
if(secondOne != null)
secondOne.Enabled = enable;
}
}
The same code, reversing the textboxes roles, could be used as the event handler of the second textbox.
Forget about control events and use data binding.
Take the following helper method
static void Bind(Control target, string targetProperty, object source, string sourceProperty, Func<object, object> expression)
{
var binding = new Binding(targetProperty, source, sourceProperty, true, DataSourceUpdateMode.Never);
binding.Format += (sender, e) => e.Value = expression(e.Value);
target.DataBindings.Add(binding);
}
and just add something like this in your form load event
Bind(textBox2, "Enabled", textBox1, "Text", value => string.IsNullOrEmpty((string)value));