I would like to have three textboxes for user input, but for each textbox I would like a different keyboard layout to be used while entering text (without the need to manually change the kayboard layout).
In textxbox 1 I would like my normal (swedish) keyboard layout to be used while I write. In the second I would like to have Japanese Hiragana layout. And in the third I would like too have Japanese Katakana layout.
Is it possible to do?
As it is now I must manually change the keyboard layout with Windowskey+Space (this cycles through all keyboard layouts).
Hope this works for you:
private void textBox1_Enter(object sender, EventArgs e)
{
// Get index of current Input Language
int currentLang = InputLanguage.InstalledInputLanguages.IndexOf(InputLanguage.CurrentInputLanguage);
// Calculate next Input Language
InputLanguage nextLang = ++currentLang == InputLanguage.InstalledInputLanguages.Count ? InputLanguage.InstalledInputLanguages[0] : InputLanguage.InstalledInputLanguages[currentLang];
// Change current Language to the calculated:
ChangeInputLanguage(nextLang);
}
public void ChangeInputLanguage(InputLanguage InputLang)
{
// Check is this Language really installed. Raise exception to warn if it is not:
if (InputLanguage.InstalledInputLanguages.IndexOf(InputLang) == -1)
throw new ArgumentOutOfRangeException();
// InputLAnguage changes here:
InputLanguage.CurrentInputLanguage = InputLang;
}
Here is the reference link - Change Input Language programmatically?
Related
I have not dealt with WinForms for a long time.
Now I'm stuck with something trivial but cannot figure it out.
I have a Winform and when a Timer Tick happens I want to show a message in a new form message box:
frmMessage frmM = new frmMessage();
frmM.txtMessage.Text = ConfigurationSettings.AppSettings["Message"];
frmM.Show();
It works but the text in the textbox shows as selected(with a blue background).
I tried
txtMessage.SelectionLength = 0;
Did not help.
Also tried to set focus to a different control, did not help either.
for now, as a workaround, I will use a Label.
This is a consequence of the way TextBox Class is implemented. If a selection is not specifically set, all text will be selected when the control gets focus.
From TextBox.OnGotFocus:
Protected override void OnGotFocus(EventArgs e) {
base.OnGotFocus(e);
If (!selectionSet) {
// We get one shot at selecting when we first get focus. If we don't
// do it, we still want to act Like the selection was set.
selectionSet = true;
// If the user didn't provide a selection, force one in.
If (SelectionLength == 0 && Control.MouseButtons == MouseButtons.None) {
SelectAll();
}
}
Additionally due to the way the SelectionLength Property is implemented, setting that property to zero does not set the selectionSet` flag as it is already zero.
Instead, set the TextBox.SelectionStart Property immediately after setting the text as this will set that flag.
txtMessage.SelectionStart = 0;
However, your work-a-round of using a Label to display a message is much more appropriate than using an input control.
This is not the best answer but it works. You can try this
frmMessage frmM = new frmMessage();
frmM.txtMessage.Text = "";
frmM.txtMessage.AppendText(ConfigurationSettings.AppSettings["Message"]);
frmM.Show();
I made a fully functional touch-keyboard within my WPF application using both XAML and C# (ofc). Currently, every key pressed on the keyboard registers the respective key in the text box; however, if the user touches the TextBox (which is welcomed...I do not want to prevent it) to position the cursor earlier in the TextBox to fix an error they might have typed AND THEN interact with the keys (as expected), the position they requested does not register and the keys continue to be entered on the end.
For example, user types(note the | acting as the cursor)::
Justin is awesome, bt that is because it is his birthday.|
User sees error in the word "but" spelled as "bt" so decides to touch the screen to position the cursor between b and t like so:
Justin is awesome, b|t that is because it is his birthday.
User expects then to touch U on the keyboard and it to be entered where the cursor appears to be...unfortunately (currently) it ends up like this:
Justin is awesome, bt that is because it is his birthday.U|
If I enable the mouse, the same thing happens (so it may not be exclusive to touch). If I plug in a keyboard after touching a position, I can type with said plugged-in keyboard no problem.
The implemented touch keyboard just wont read the position correctly. Looking at this, the action seems to go no where because the Cursor Position goes from the TextBox to a Button (keyboard keys).
Here's a snippet of code for anyone to test (obviously can't provide the full keyboard):
XAML
<Grid>
<TextBox x:Name="txtBox" />
<Button x:Name="btnQ" Content="q" Click="btnQ_Click"/>
<Button x:Name="btnW" Content="w" Click="btnW_Click"/>
</Grid>
C#
private bool numberHitSinceLastOperator = false;
private void HandleKeyboard(string key)
{
//Ternary operator
string valueSoFar = numberHitSinceLastOperator ? txtBox.Text : "";
string newValue = valueSoFar + key.ToString();
txtBox.Text = newValue;
numberHitSinceLastOperator = true;
}
private void btnQ_Click(object sender, RoutedEventArgs e)
{
HandleKeyboard("Q");
}
private void btnW_Click(object sender, RoutedEventArgs e)
{
HandleKeyboard("W");
}
Your problem is this line:
string newValue = valueSoFar + key.ToString();
You are always appending at the end. To append at the right position, you can do something like this:
int oldCaretIndex = txtBox.CaretIndex;
txtBox.Text = txtBox.Text.Insert(text.CaretIndex, "a");
//changing Text resets the caret position to 0
txtBox.CaretIndex = oldCaretIndex + 1;
You could also try simulating key presses, see for example here: How can I programmatically generate keypress events in C#?
Or, like the commenter suggested, try the SurfaceSDK (though I haven't used it myself).
I'm using the RichEditBox to build a simple editor.
I found a piece of code which toggles bold text on a selection within the document window
private void RichEditBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
var state = Window.Current.CoreWindow.GetKeyState(Windows.System.VirtualKey.Control);
if ((state & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down)
{
if (e.Key == Windows.System.VirtualKey.B)
{
if (Editor.Document.Selection.Text.Length > 0)
{
ITextCharacterFormat format = Editor.Document.Selection.CharacterFormat;
format.Bold = FormatEffect.On;
}
else
{
// CTRL + B should toggle bold mode on or off here.
}
}
}
}
When I highlight a piece of text, and press CTRL+B, it bolds the text. Result. However, anything I type after that point is also in bold.
This is not what I expected. According to the code above, I'm affecting the format of the Selection only.
When I select some text and press CTRL+B it should toggle bold formatting on that selection and leave the default format as is.
I've tried using FormatEffect.Toggle
format.Bold = FormatEffect.Toggle
I've tried saving out the Document Character format first, then reapplying
ITextCharacterFormat original_format = Editor.Document.GetDefaultCharacterFormat();
ITextCharacterFormat format = Editor.Document.Selection.CharacterFormat;
format.Bold = FormatEffect.On;
Editor.Document.SetDefaultCharacterFormat(original_format);
This should reset the default back to what it was after bolding. But it doesn't
I could set the selection to nothing, then set format.Bold = FormatEffect.Off again, then reselect the text, but that seems like the long way around (and it probably won't work). There must be a simple way to do this?
NOTE: I have tagged this with the RichTextBox tag as there is no RichEditBox tag. Can someone with >1500 rep add one?
That's the normal behaviour when using SelectionFont and setting bold style with richtextbox.
If the current text selection has more than one font specified, this
property is null. If no text is currently selected, the font specified
in this property is applied to the current insertion point and to all
text that is typed into the control after the insertion point.
It's probably the same issue that you have.
Wordpad and Word work this way too.
I have found a hack, that works. I'm posting this as an answer for anyone who's stuck, but I'm not accepting the answer, because there must be a better one.
private void RichEditBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
var state = Window.Current.CoreWindow.GetKeyState(Windows.System.VirtualKey.Control);
if ((state & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down)
{
if (e.Key == Windows.System.VirtualKey.B)
{
if (Editor.Document.Selection.Text.Length > 0)
{
// text is selected. make it bold
ITextCharacterFormat format =
Editor.Document.Selection.CharacterFormat;
format.Bold = FormatEffect.On;
var start_pos = Editor.Document.Selection.StartPosition;
Editor.Document.Selection.StartPosition =
Editor.Document.Selection.EndPosition;
format.Bold = FormatEffect.Off;
// Editor.Document.Selection.StartPosition = start_pos;
// this is where I was re-selecting the text after switching bold OFF
// but doing so switches it back on again. which makes no sense
}
else
{
// no text selected. just enable bold mode
ITextCharacterFormat format =
Editor.Document.Selection.CharacterFormat;
format.Bold = FormatEffect.Toggle;
}
}
}
}
This isn't perfect, because after you've selected and bolded the text it is automatically de-selected. However in practice I find that this actually works fine for me. Still, it feels like a hack, because it is a hack
How to validate text in textbox control in winforms?
I have a control, where user have to put string, like "13:55". I want to show MessageBox, when this value will be diffrent, than "XX:YY".
How to do it?
In asp.net it was so easy to make, but how to implement it on winforms?
Check out the MaskedTextBox if you don't want to have to validate in the first place.
var l_control = new MaskedTextBox();
l_control.Mask = "00\:00";
If you want to make the first digit optional:
l_control.Mask = "90\:90";
Otherwise, you could use a regular expression. 4 digits separated by a colon would be: #"^\d{2}:\d{2}$". (The # symbol prevents C# from treating '\' as an escape character - nothing unique to regex.)
There are three validation videos at http://windowsclient.net/learn/videos.aspx that will walk you through the whole process.
But using a Masked Textbox might be easier, depending on what you are collecting for data.
Heck, for what you're doing, you could be really safe and use two NumericUpDown controls and not have to deal with the validation at all.
You should take a look at C# Regex
Match match = Regex.Match(input, "^\d\d:\d\d$"));
if (!match.Success) MessageBox.Show("Error");
You could also use an ErrorProvider instead of popping up a messagebox. An example is available on msdn for the ErrorProvider class. Basically you subscribe to the Validated event
this.nameTextBox1.Validated += nameTextBox1Validated;
and then check if the value is valid
private void nameTextBox1Validated(object sender, EventArgs e) {
if(isNameValid()) {
// clear error
nameErrorProvider.SetError(nameTextBox1, String.Empty);
}
else {
// set some helpful message
nameErrorProvider.SetError(nameTextBox1, "Invalid value.");
}
}
private bool isNameValid() {
// The logic for determining if a value is correct
return nameTextBox1.Text == "hello";
}
the error provider can be created like this
ErrorProvider nameErrorProvider = new ErrorProvider();
nameErrorProvider.SetIconAlignment(nameTextBox1, ErrorIconAlignment.MiddleRight);
nameErrorProvider.SetIconPadding(nameTextBox1, 2);
nameErrorProvider.BlinkRate = 1000;
nameErrorProvider.BlinkStyle = ErrorBlinkStyle.AlwaysBlink;
I have a form containing a TextBox in C# which I set to a string as follows:
textBox.Text = str;
When the form is displayed, why does the text in the texbox appear highlighted/selected?
The text box has a TabIndex of 0 and TabStop set to true. This means that the control will be given focus when the form is displayed.
You can either give another control the 0 TabIndex (if there is one) and give the text box a different tab index (>0), or set TabStop to false for the text box to stop this from happening.
The default behavior of a TextBox in Windows Forms is to highlight all of the text if it gets focused for the first time by tabbing into it, but not if it is clicked into. We can see this in Reflector by looking at the TextBox's OnGotFocus() override:
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
if (!this.selectionSet)
{
this.selectionSet = true;
if ((this.SelectionLength == 0) && (Control.MouseButtons == MouseButtons.None))
{
base.SelectAll();
}
}
}
It's that if statement that is causing the behavior that we don't like. Furthermore, to add insult to injury, the Text property's setter blindly resets that selectionSet variable whenever the text is re-assigned:
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
this.selectionSet = false;
}
}
So if you have a TextBox and tab into it, all the text will be selected. If you click into it, the highlight is removed, and if you re-tab into it, your caret position (and selection length of zero) is preserved. But if we programmatically set new Text, and tab into the TextBox again, then all of the text will be selected again.
If you are like me and find this behavior annoying and inconsistent, then there are two ways around this problem.
The first, and probably the easiest, is to simply trigger the setting of selectionSet by calling DeselectAll() on form Load() and whenever the Text changes:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.textBox2.SelectionStart = this.textBox2.Text.Length;
this.textBox2.DeselectAll();
}
(DeselectAll() just sets SelectionLength to zero. It's actually SelectionStart that flips the TextBox's selectionSet variable. In the above case, the call to DeselectAll() is not necessary since we are setting the start to the end of the text. But if we set it to any other position, like the start of the text, then calling it is a good idea.)
The more permanent way is to create our own TextBox with the desired behavior through inheritance:
public class NonSelectingTextBox : TextBox
{
// Base class has a selectionSet property, but its private.
// We need to shadow with our own variable. If true, this means
// "don't mess with the selection, the user did it."
private bool selectionSet;
protected override void OnGotFocus(EventArgs e)
{
bool needToDeselect = false;
// We don't want to avoid calling the base implementation
// completely. We mirror the logic that we are trying to avoid;
// if the base implementation will select all of the text, we
// set a boolean.
if (!this.selectionSet)
{
this.selectionSet = true;
if ((this.SelectionLength == 0) &&
(Control.MouseButtons == MouseButtons.None))
{
needToDeselect = true;
}
}
// Call the base implementation
base.OnGotFocus(e);
// Did we notice that the text was selected automatically? Let's
// de-select it and put the caret at the end.
if (needToDeselect)
{
this.SelectionStart = this.Text.Length;
this.DeselectAll();
}
}
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
// Update our copy of the variable since the
// base implementation will have flipped its back.
this.selectionSet = false;
}
}
}
You maybe tempted to just not call base.OnGotFocus(), but then we would lose useful functionality in the base Control class. And you might be tempted to not mess with the selectionSet nonsense at all and simply deselect the text every time in OnGotFocus(), but then we would lose the user's highlight if they tabbed out of the field and back.
Ugly? You betcha. But it is what it is.
The answers to this question helped me a lot with a similar problem, but the simple answer is only hinted at with a lot of other complex suggestions. Just set SelectionStart to 0 after setting your Text. Problem solved!
Example:
yourtextbox.Text = "asdf";
yourtextbox.SelectionStart = 0;
You can also choose the tab order for your form's controls by opening:
View->Tab Order
Note that this option is only available in "View" if you have the Form design view open.
Selecting "Tab Order" opens a view of the Form which allows you to choose the desired tab order by clicking on the controls.
To unhighlight a text field, with VS 2013, try init with:
myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);
And add the method:
public void myTextBox_GotFocus(object sender, EventArgs e)
{
myTextBox.SelectionLength=0;
}
I haven't tested this on C# but I ran into the same issue using a C++ WIN32 dialog box. Is seems like you can change the behavior by returning FALSE from OnInitDialog() or WM_INITDIALOG. Hope this helps.
Here is what worked for me
public void SetNotes(string notes)
{
notesTextBox.Text = notes;
notesTextBox.Select();
notesTextBox.SelectionLength = 0;
notesTextBox.SelectionStart = notes.Length;//place cursor at end of text
}