How can i open a form everytime a textbox is focused? - c#

im developing a keyboard to a touchscreen display, i need to know how can i program a generic code that everytime any textbox is focused, the form(keyboard) opens. I know i could put in the event focus of every single textbox, but i want to do a generic code. Im working with WCE8 and .net compact framework 3.5.

You could create your own custom control and override the OnGotFocus function
public partial class FocusTextBox : TextBox {
public FocusTextBox() {}
protected override void OnGotFocus(EventArgs e) {
// Your code to open the keyboard here
base.OnGotFocus(e);
}
}

You can find all the control type textbox in your control and gives them the click event with a foreach, for instance
foreach(Control ctrl in panel1.Controls)
{
if(ctrl is TextBox)
{
ctrl.Click += new EventHandler(OpenSecondForm_Click);
}
}
private void OpenSecondForm_Click(object sender, EventArgs e)
{
Form2 form = new Form2();
form.Show();
}
in this way, every time you focused any textbox,it will open a second form, I hope this can help you.

Related

Windows Forms click event not fired when clicking on label?

I have Windows Form TestForm, and in my Form I have several labels that are only used to display some text.
I need to display a MessageBox.Show anytime the Form is clicked. So I have an event handler for the click, which looks like this:
private void TestForm_Click(object sender, EventArgs e)
{
MessageBox.Show("The form has been clicked");
}
Unfortunately, the click event doesn't fire when I click over a label in the Form. Is there a way to fix this, besides consuming the click event for the labels?
Thanks.
To use the same click event for all labels:
In the properties for each label, go to the Events (lightning bolt tab).
You will see (probably near the top) a label for Click, click the dropdown for this event, and you will be shown a list of handlers that you could use for that label.
Here's the Properties > Events > Click handler (bottom right):
Because all of your labels are of the same type, and produce the same EventArgs, you are able to use the same handler for all of them.
Then, when you are adding more Labels, just choose the event handler from the Click event dropdown:
Hope this helps!
To flesh out LarsTech's comment, I have used something like this in the past when I was having problems with labels overlapping each other and lack of true transparency in WinForms. What I did was make the labels invisible on the Form, then iterate through them in the Form's paint event, pull the information out of them and then use Graphics.DrawString to draw the text. That way you you will still be able see them in design mode.
This is a quick example of what I mean.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
foreach (var temp in this.Controls)
{
if (temp is Label) //Verify that control is a label
{
Label lbl =(Label)temp;
e.Graphics.DrawString(lbl.Text, lbl.Font, new SolidBrush(lbl.ForeColor), new Rectangle(lbl.Location, lbl.Size));
}
}
}
private void Form1_Click(object sender, EventArgs e)
{
MessageBox.Show("The Form has been clicked");
}
}

Pass KeyDown event to other control

I am writing a C# WinForms application, .NET 4.0.
I have a WinForms Control on a Form. After user starts typing something using keyboard, another Control appears. That Control is some kind of text input. I'd like to send user input to that Control. Of course, after it gets focused, it receives all user keyboard input. But as user starts typing before Control appears, I have to pass first KeyDown event to that control after I call it's Show and Focus methods.
SendKeys.Send method is a way of doing something similar. But that is so complicated, and seems to be unsafe. I have just a value of Keys enumeration from KeyData property of KeyEventArgs, I'd like to use it, not transform it to some strange string.
Is there any good way to pass KeyDown event from one control to another?
You can use PreviewKeyDown on Form.
Suppose you want to send keyboard inputs to TextBox textBox1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.PreviewKeyDown+= Form1_OnPreviewKeyDown;
textBox1.Visible = false;
}
private bool _textboxEnable = false;
private void Form1_OnPreviewKeyDown(object sender, PreviewKeyDownEventArgs previewKeyDownEventArgs)
{
if (!_textboxEnable) textBox1.Visible = true;
if (!textBox1.Focused) textBox1.Focus();
}
}
Any reason you can't just pass the event onto the "child control" ? Below example is KeyPress but the same idea applies for KeyDown
//Parent Control Visible
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
richTextBox1_KeyPress(sender, e);
}
//Child Control Hidden
private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
richTextBox1.Text += e.KeyChar.ToString();
}
You can make a custom control which inherites the a textbox. YOu can place that custom control instead. In that custom control you can write a method which calls it:
public class MyTextBox : TextBox
{
public void TriggerKeyPress(KeyPressEventArgs e)
{
this.OnKeyPress(e);
}
}
If you dont want to make use of custom controlls you can make an extension to a textbox and use reflection to call it:
public static class TextBoxExtensions{
public static void TriggerKeyPress(this TextBox textbox, KeyPressEventArgs e)
{
MethodInfo dynMethod = textbox.GetType().GetMethod("OnKeyPress",
BindingFlags.NonPublic | BindingFlags.Instance);
dynMethod.Invoke(textbox, new object[]{ e });
}
}
But with both methods you should know: This will not add the text from one object to another. To do that you will have to write that in your code manually.

Put focus back on previously focused control on a button click event C# winforms

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".

Prevent button getting focus

I have a solution with several forms, each may have TextBox's/controls and a button to show the SIP (the bottom bar is hidden).
When the user clicks my SIP button, the SIP is enabled but the focus is now the button. I want the user to click the button - the SIP to display but the focus to remain on the control that had the focus before the user clicked the button. Does anyone know how to do this? Thanks.
Instead of using an standard button, you can create a custom one by deriving from the Control class and overriding the OnPaint method. A control created this way will not claim the focus by default when treating the Click event (tested on VS2008 netcf 2.0).
public partial class MyCustomButton : Control
{
public MyCustomButton()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
pe.Graphics.DrawString("Show SIP", Font, new SolidBrush(ForeColor), 0, 0);
// Calling the base class OnPaint
base.OnPaint(pe);
}
}
The solution of nathan will work also for Compact Framework or native Windows Mobile applications. In the textbox GotFocus set a global var and use this in the buttons click event to set the focus back to the last active textbox:
//global var
TextBox currentTB = null;
private void button1_Click(object sender, EventArgs e)
{
inputPanel1.Enabled = !inputPanel1.Enabled;
if(currentTB!=null)
currentTB.Focus();
}
private void textBox1_GotFocus(object sender, EventArgs e)
{
currentTB = (TextBox)sender;
}
regards
Josef
Edit: Solution with subclass of TextBox:
class TextBoxIM: TextBox{
public static TextBox tb;
protected override void OnGotFocus (EventArgs e)
{
tb=this;
base.OnGotFocus (e);
}
}
...
private void btnOK_Click (object sender, System.EventArgs e)
{
string sName="";
foreach(Control c in this.Controls){
if (c.GetType()==typeof(TextBoxIM)){
sName=c.Name;
break; //we only need one instance to get the value
}
}
MessageBox.Show("Last textbox='"+sName+"'");
}
Then, instead of placing TextBox use TextBoxIM.

Which control has been clicked?

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;
}

Categories