I've searched relevant posts but I got nothing much
I have created a user control. In my user control there is a text box. I want to have an event in my user control that fires whenever text box TextChanged event raises. This is what I have done so far : (This is code of user control)
public event EventHandler txtchnged;
public void ontxtchnged()
{
txtchnged(this, EventArgs.Empty);
}
public MyTextBox()
{
InitializeComponent();
textBox1.TextChanged += textBox1_TextChanged;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
ontxtchnged();
}
Here is where I have used user control
public RegisterMainFrm()
{
InitializeComponent();
myUserControl1.txtchnged += myUserControl1_txtchnged;
}
private void myUserControl1_txtchnged(object sender, EventArgs e)
{
Console.WriteLine("hello");
}
This works and I know that the code might not be clean but that's not the problem. Problem is : "hello" will be printed in console twice and I really don't know why and how to fix it.
From MSDN on TextBox.TextChanged:
Note:This event fires when the TextBox control is created and
initially populated with text.
Could this be your problem that you get the initial event?
UPDATE:
From Adriano Repetti Hint in Comments: Did you get the textBox1_TextChanged event handler by double clicking in the designer?
Then you have added a second hook to the TextChanged Event.
Check the code inside InitializeComponent of your UserControl if it is already hooking the event.
Related
I have a TextBox and I want all the text inside of it to be highlighted when the user clicks on it (so that they can replace it easily). I have the following event handler linked up the the TextBox:
private void TextBox_Enter(object sender, EventArgs e) {
SelectAll();
}
When I click on the TextBox, the text is only selected for a fraction of a second (sometime it's so fast I can't see it at all) and then it goes back to being a cursor. Does anyone know how to fix this or if there are any relatively simple workarounds?
I tried the same thing with the TextBox.MouseClick event (and it highlighted the text), but because it was the MouseClick event the text was highlighted every time I clicked the TextBox (even when the TextBox already had focus).
I have also tried SelectionStart = 0; SelectionLength = Text.Length, but the same thing happens. This leads me be believe the issue has something to do with the event.
I also tried the TextBox.GotFocus event and had the exact same problem.
I am doing this in a Windows Form application.
The reason why you didn't see the text getting selected is that the TextBox is busy when one of those events occurred (e.g., caret positioning). You actually select the text, but then the internal event handlers of the TextBox execute and remove the selection e.g. by setting the caret position.
All you have to do is to wait until the internal event handlers have completed.
You do this by using the Dispatcher. When you invoke the Dispatcher asynchronously the delegate is not immediately executed but enqueued and executed once all previously enqueued actions (like the internal event handlers) are cleared from the dispatcher queue.
So going with the TextBox.GotFocus event in WPF (or the TextBox.Enter in WinForms) and the asynchronous Dispatcher will do the trick:
WPF
private async void SelectAll_OnTextBoxGotFocus(object sender, RoutedEventArgs e)
{
await Application.Current.Dispatcher.InvokeAsync((sender as TextBox).SelectAll);
}
WinForms
private void SelectAll_OnTextBoxEnter(object sender, EventArgs e)
{
var textBox = sender as TextBox;
textBox.BeginInvoke(new Action(textBox.SelectAll));
}
Thankfully I found a solution! It turns out that the Click event is executed before the Enter event, this allowed me to set up a JustGotFocus variable and do the following:
private void myTextBox_Click(object sender, EventArgs e) {
this.JustGotFocus = true;
if (JustGotFocus) {
myTextBox.SelectAll();
}
}
private void myTextBox_Enter(object sender, EventArgs e) {
JustGotFocus = false;
}
If anyone else has this problem hopefully my solution is useful.
I have just a little problem with reading text from label, but...
I have two forms. Form_1, and Form_2.
Form_1 is sending (on demand) text from "label_one" directly to "label_two" in Form_2.
But in Form_2 i have another label called "label_reader" that need to show any changes done in "label_two" text.
I must (dynamically?) read any changes from "label_two" and show it in label_reader.
Never had a similar problem, and have no idea how to do that. It can't be done with the use of a button.
Any help will be greatly appreciated!
You can use the TextChanged event of label_two. Subscribe to that event (most likely in the constructor of your Form_2) and set the text of label_reader when the event is raised:
public partial class Form_2 : Form
{
//...
public Form_2()
{
InitializeComponent();
// your other code
label_two.TextChanged += label_two_TextChanged;
}
// the event handler
private void label_two_TextChanged(object sender, EventArgs e)
{
label_reader.Text = label_two.Text; // or what ever you want to do
}
}
I have a winforms app in vs2010 and a panel whose click event I would like to fire programatically. How do I do this? Button has a PerformClick but I cannot find the same in Panel.
Your panel's Click event is going to be attached to an event handler, right?
Then just call that event handler from the button's click event handler:
public void Panel1_Click(object sender, EventArgs e)
{
//Do whatever you need to do
}
public void Button1_Click(object sender, EventArgs e)
{
//Do anything you need to do first
Panel1_Click(Panel1, EventArgs.Empty);
}
The effect will be the same as clicking on the panel.
I have made a custom Number Keypad control that I want to place in my winform application. All of the buttons have an OnClick event to send a value to the focused textbox in my form where I have placed my custom control. Like this:
private void btnNum1_Click(object sender, EventArgs e)
{
if (focusedCtrl != null && focusedCtrl is TextBox)
{
focusedCtrl.Focus();
SendKeys.Send("1");
}
}
focusedCtrl is supposed to be set on the MouseDown event of the button like this:
private void btnNum1_MouseDown(object sender, EventArgs e)
{
focusedCtrl = this.ActiveControl;
}
where this.ActiveControl represents the active control on the form.
My problem is that the button always receives the focus before the event detects what the focused control was previously. How can I detect which control had the focus before the button got the focus? Is there another event I should be using? Thanks in advance!
EDIT: Also, I would rather not use the GotFocus event on each textbox in the form to set focusedCtrl since that can be tedious and because I would like to have all the coding of my custom control be in the control itself and not on the form where it is placed. (I will do this, though, if there is no other practical way to do what I am asking)
Your requirement is fairly unwise, you'll want some kind of guarantee that your button isn't going to poke text into inappropriate places. You really do need to have the form co-operate, only it knows what places are appropriate.
But it is not impossible, you can sniff at input events before they are dispatched to the control with the focus. In other words, record which control has the focus before the focusing event is fired. That's possible in Winforms with the IMessageFilter interface.
Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form, replacing your existing buttons.
using System;
using System.Windows.Forms;
class CalculatorButton : Button, IMessageFilter {
public string Digit { get; set; }
protected override void OnClick(EventArgs e) {
var box = lastFocused as TextBoxBase;
if (box != null) {
box.AppendText(this.Digit);
box.SelectionStart = box.Text.Length;
box.Focus();
}
base.OnClick(e);
}
protected override void OnHandleCreated(EventArgs e) {
if (!this.DesignMode) Application.AddMessageFilter(this);
base.OnHandleCreated(e);
}
protected override void OnHandleDestroyed(EventArgs e) {
Application.RemoveMessageFilter(this);
base.OnHandleDestroyed(e);
}
bool IMessageFilter.PreFilterMessage(ref Message m) {
var focused = this.FindForm().ActiveControl;
if (focused != null && focused.GetType() != this.GetType()) lastFocused = focused;
return false;
}
private Control lastFocused;
}
Control focusedCtrl;
//Enter event handler for all your TextBoxes
private void TextBoxesEnter(object sender, EventArgs e){
focusedCtrl = sender as TextBox;
}
//Click event handler for your btnNum1
private void btnNum1_Click(object sender, EventArgs e)
{
if (focusedCtrl != null){
focusedCtrl.Focus();
SendKeys.Send("1");
}
}
you have an event called lostFocus you can use
button1.LostFocus +=new EventHandler(dataGridView1_LostFocus);
and in the event:
Control lastFocused;
void dataGridView1_LostFocus(object sender, EventArgs e)
{
lastFocused = sender as Control;
}
in that way you can always know what is the Control that was focused previously
now, correct me if i'm wrong, but you do it for the SendKeys.Send("1"); to know which textBox need to receive the number. for that you can use GotFocus event and register only the textBoxs to it.
you can also do what windows is doing and use just one textbox like here:
if it's fits your needs
What about using this with the parameter forward = false?
Control.SelectNextControl Method
You'd probably call it on your "custom Number Keypad control".
I have a problem with MouseEvents on my WinForm C# application. I want to get ALL mouse clicks on my application.
How to determine which control has been clicked ?(I'm beginner C#)
Try this:
private void Control_Clicks(object sender, EventArgs e)
{
Control control = (Control)sender; // Sender gives you which control is clicked.
MessageBox.Show(control.Name.ToString());
}
This, this or this may help.
Hope it helps.
private void Form1_Load(object sender, EventArgs e)
{
SetupClickEvents(this);
}
/// <summary>
/// This will loop through each control within the container and add a click handler to it
/// </summary>
/// <param name="container">The container whose children to handle clicks for</param>
private void SetupClickEvents(Control container)
{
foreach(Control control in container.Controls)
{
control.Click += HandleClicks;
}
}
private void HandleClicks(object sender, EventArgs e)
{
Control control = (Control)sender;
MessageBox.Show(string.Format("{0} was clicked!", control.Name));
}
If you're doing Windows Forms, you have several options :
Hook mouse event, and after figure out if the clicked component actually makes part of your application
You can declare a base class MyComponent : Control. That component overrides MousClick event and raise a special event notifying about a fact. Every control in your app derive from that control, so every control will notify about click happened on it. It's enough to subcribe
to thier events and process them as requested.
Just a couple of ideas...
You'd have to wire them all up to the same event handler. This can be done in the properties window for the controls in question. You could also write your own function to traverse the control tree and tie the function to each of their event handlers.
You can recursively traverse the Form.Controls collection with a foreach loop.
void attachGlobalHandler(Control aToParse, EventHandler aGlobalHandler)
{
foreach(Control lControl in aToParse.Controls)
{
attachGlobalHandler(lControl, aGlobalHandler);
lControl.Click += aGlobalHandler;
}
}
And then you call that on your form, with the name of the function you want to call:
attachGlobalHandler( Form1, myClickHandler );
And that should tie it to EVERY clickable control on the form. The sender argument of the handler should then always refer to the control that fired the event. That being said, I'd probably just attach individual event handlers, unless you need to treat multiple controls as a group.
WARNING: The code above is untested.
For the second question asked "How to determine which control has been clicked?" each control has events which may be handled in code.
The easiest way to know when a control has been clicked is to attached to the clicked event of a control which is done from the properties for the control. You may have to click the lightning bolt icon to see the events. Double-clicking beside the even will create an empty handler.
For example if you had a simple form with a single button attaching click events to the form and to the button will tell you when there is a click anywhere. In most cases the button click would be the most useful to handle.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Click(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
}
}
It's really simple!
On your click event in your Win-Form, You add
// Here is a modified version of your code:
private void Form1_Click(object sender, EventArgs e)
{
var control = Form1.ActiveControl;
}