Does anyone know how I could easily detect if the Windows OS IME (Input Method Editor) is active in the Silverlight framwork. Let me explain the scenario which is causing me issues:
I have hit an issue where using a Chinese (Simplified, China) Microsoft Pinyin causes a CLR exception. The scenario is when a TextBox is handling its TextChanged event. For example:
A TextBox should not accept characters but only numbers. In order to achieve that it is handling its TextChanged event and in that event it handles the input by reversing its Text property to the last correct input character by character. In this scenario if an (Chinese (Simplified, China) Microsoft Pinyin) IME is used an a FatalExecutionEngineError is thrown.
In WPF it is possible to overcome this issue by not reversing the Text in the TextChanged event by using the InputMethod.Current.ImeState to check if an IME is active. Unfortunately this is not available in the Silverlight framework which is why I am posting this question.
Currently the only thing I have found is that I could set IsInputMethodEnabled property of the InputMethod class to the TextBox control in order disable all IME input but this of course will not only disable the incorrect input but also the correct one.
Anyone has any ideas how I could detect if a IME is used/active in the Silverlight platform? Thanks.
I was able to resolve the issue in both the WPF and Silverlight frameworks. The issue was caused by the fact that by handling the TextBox Text while a IME is inputting symbols that Text was making the IME itself change its input which it looks like is not handled gracefully by the Windows OS and was causing a CLR exception.
What I did was:
In the WPF framework as mentioned I used the static InputMethod.Current.ImeState value to determine if IME is active and if it was with On value I skipped reverting the TextBox Text property in its TextChanged event.
In the Silverlight framework I use a combination of the TextInputStart, TextInputUpdate events and a local private field to store if IME was detected. The TextInputUpdate event is only triggered if IME is active and used as input and the TextInputStart is always triggered. What I did was:
Created a bool IsImeActive = false; filed
Hook to the TextInputStart event of the TextBox
In that event set the IsImeActive field to False
Hook to the TextInputUpdate event of the TextBox
In that event set the IsImeActive field to True
Finally in the TextChanged event add a condition that checks the IsImeActive field and if it is False run the logic which handles (reverses) the input.
Hope this is helpful.
I also get FatalExecutionEngineError, error code 0x80131623 when some IME is active.
My fix: I could get IME event with
TextCompositionManager.AddPreviewTextInputHandler(myTextbox, OnPreviewTextInput);
TextCompositionManager.AddPreviewTextInputStartHandler(myTextbox, OnPreviewTextInputStart);
TextCompositionManager.AddPreviewTextInputUpdateHandler(myTextbox, OnPreviewTextInputUpdate);
private void OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
ImeFlag = false;
}
private void OnPreviewTextInputStart(object sender, TextCompositionEventArgs e)
{
ImeFlag = true;
}
private void OnPreviewTextInputUpdate(object sender, TextCompositionEventArgs e)
{
if (e.TextComposition.CompositionText.Length == 0)
ImeFlag = false;
}
I remove any TextChanged event when current IME is active, then add back event after an IME text is completed:
private bool _imeFlag = false;
private bool ImeFlag
{
get => _imeFlag;
set
{
if (_imeFlag == value)
return;
if (value)
myTextbox.TextChanged -= MyTextbox_TextChanged;
else
myTextbox.TextChanged += MyTextbox_TextChanged;
_imeFlag = value;
}
}
Related
I am creating a program that has a lot of user inputs. Most of the user inputs are going to be in TextBoxes that need to be only numeric entries.
Currently, I am just using a TextChanged method for getting values, which then make other buttons/checkboxes show/hide based on the entry.
I am wanting to create a method or implement some kind of utilization that checks when is being inputted into the boxes, to either prevent people from making incorrect inputs, to fix changes that they had made, or to create a messagebox that will tell them that their input is invalid.
I have two ways I am currently working with but they don't work with each other.
I have a parse method, that converts the input text into a Double but the problem I am running into, if they utilize the backspace button then re-enter their numbers, it will not recognize the input (which is needed to open/close other textboxes/checkboxes). This does work with the TextChanged method.
I have a regex set that utilizes the PreviewTextInput and KeyDown methods. This works pretty well with not allowing certain inputs but it doesn't work with the textchanged method (or at least I don't understand how to point to it).
I am in need of some guidance on how to create a viable method for checking inputs into textboxes that doesn't require my users to press a button for each entry (aka checking real-time).
I think this is what you are looking for.
Binding.Validation
For an Int it is as easy as just binding to an Int.
If you need to be able to increase/decrease the value via button use NumericUpDown or one of its subclass.
If you just need a textbox, you have to handle PreviewKeyDown() event. You need to manually check for valid/invalid keys pressed. When an invalid key is pressed, you set e.Handled = true; to prevent the key down event from tunneling down.
I really couldn't understand completely, but according to me you are trying to prevent a textbox to take invalid input and at the same time you want to use TextChanged method, so you can do like this:
<TextBox Name="txtAddNumber" TextChanged="txtAddLable_TextChanged" PreviewTextInput="txtAddNumber_PreviewTextInput" />
And txtAddNumber_PreviewTextInput method:
private void txtAddNumber_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
char c = Convert.ToChar(e.Text);
if (!Char.IsLetter(c))
e.Handled = false;
else
e.Handled = true;
base.OnPreviewTextInput(e);
}
And if you want to handle some error message kind of thing on the base of input you can do like this:
private void txtAddNumber_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
char c = Convert.ToChar(e.Text);
if (!Char.IsLetter(c))
{
// Put your Logic here according to requirement
e.Handled = false;
}
else
{
// Put your Logic here according to requirement
e.Handled = true;
}
base.OnPreviewTextInput(e);
}
And
e.Handled = false means input is numeric and e.Handled = true means input is non-numeric.
And your txtAddLable_TextChanged method will bw like:
private void txtAddLable_TextChanged(object sender, TextChangedEventArgs e)
{
// Logics here...
}
I have a TextBox. After leaving the textBox the first character should be a capital Letter.
Three Events work as same. They are Leave,Validating and Validated.
if (txtLocl.Text.Length > 0)
txtLocl.Text = txtLocl.Text.Substring(0, 1).ToUpper() + txtLocl.Text.Substring(1);
Which event of these 3 events should I use?
You can subscribe to the Control.Leave event which will be fired when the control loses focus. Originally, I thought using Control.LostFocus would be the most appropriate event to use but it is not available via the designer meaning you would need to manually subscribe to the event which is a bit ugly and unconventional in my opinion.
private void inputTextBox_Leave(object sender, EventArgs e)
{
if (inputTextBox.Text != string.Empty)
{
string input = inputTextBox.Text;
inputTextBox.Text = input.First().ToString(CultureInfo.InvariantCulture).ToUpper() +
string.Join(string.Empty, input.Skip(1));
}
}
You sound like you're interested in Control.Validating. The advantage of using Control.Validating is that you can utilize the event handler's given argument; CancelEventArgs and set the Cancel property to true. What this will do is stop the control from losing focus and forcing the user to enter a valid value. I don't think this is appropriate for your application as you are not really validating anything but formatting the input.
private void inputTextBox_Validating(object sender, CancelEventArgs e)
{
if (inputTextBox.Text == string.Empty)
{
statusLabel.Text = "The given input is not valid.";
e.Cancel = true;
}
}
Bear in mind that when the form closes, all controls subsequently lose focus and the Control.Validating event is fired which could stop the Form closing until all fields pass their relative validation checks. If you find yourself needing to avoid this behavior a quick search will prevail.
There are many other events also available.
As said by MSDN, When you change the focus by using the keyboard (TAB, SHIFT+TAB, and so on), by calling the Select or SelectNextControl methods, or by setting the ContainerControl.ActiveControl property to the current form, focus events occur in the following order:
1) Enter
2) GotFocus
3) Leave
4) Validating
5) Validated
6) LostFocus
When you change the focus by using the mouse or by calling the Focus method, focus events occur in the following order:
1) Enter
2) GotFocus
3) LostFocus
4) Leave
5) Validating
6) Validated
If the CausesValidation property is set to false, the Validating and Validated events are suppressed.
textBox1_Leave is appropriate for you.
Check the events and description about textboxes over here>>
http://msdn.microsoft.com/en-us/library/system.windows.forms.textbox_events.aspx
Hope its helpful.
You might want to subscribe to LostKeyboardFocus event (in WPF) or Leave event (in WF).
I'd suggest using the Leave because I assume you aren't validating the value, but formatting it. Validating and Validated should contain code for validation and the aftermath of validation respectively, IMO.
Is there any event that fire when the value of the textbox change from a peace of code and when the textbox is validated or lost the focus and the event don't fire on the key press,because I have a lot of calculation and It's not possible to do it on every key press
Use TextChanged for text changed.
Use LostFocus for when textbox looses focus.
Use Validating or Validated for validation.
Here is the order in which events are called for TextBox:
// Reference : http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validated.aspx
1) Enter
2) GotFocus
3) Leave
4) Validating
5) Validated
6) LostFocus
This should help you decide where you want to put your code.
There's no event that will fulfill your requirement of being raised when the textbox's value is changed programmatically through code, but not when text is typed into it by the user. The TextChanged event is going to be raised either way (this is fairly intuitive—the text value is changing, and the computer doesn't know or care what is responsible for changing it). As the documentation for this event indicates:
User input or setting the Text property to a new value raises the TextChanged event.
If you need to run custom validation logic when you add text to your textbox in code, you will need to invoke whatever method contains the validation logic yourself. Extract it into a separate method, which you call from the Validating/Validated event handler and from all of the places in your code where you set the textbox's Text property.
As a supplement to the other answers that have already been posted, I strongly recommend using either the Validating (if you want to be able to cancel the validation) or Validated events to handle the textbox losing focus, rather than the somewhat more obviously named LostFocus event.
You can use the LostFocus or Validated events.
Use a member variable.
private bool _changeByCode;
public void DoSomeChanges()
{
_changeByCode = true;
textbox1.Text = "Hello";
_changeByCode = false;
}
public void Textbox1_Change(object source, EventArgs e)
{
if (_changeByCode)
return;
//do your validation here.
}
I have a custom RichTextBox Control derived from RichTextBox Control that Windows provides.
I am unable to capture the dragDrop Event though the DragEnter event is getting captured, but I dont know why the dragDrop event is not.
I have following properties set as true:
EnableAutoDragDrop=true;
AllowDrop=true;
What am I missing ??
Daniel is probably correct here:
private void DragOver(object sender, System.Windows.Forms.DragEventArgs e)
{
if (!e.Data.GetDataPresent(typeof(System.String))) {
e.Effect = DragDropEffects.None;
DropLocationLabel.Text = "None - no string data.";
return;
}
see also the example in:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.dodragdrop.aspx
You need DragDrop and DragOver in your RichTextBox.
http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_26532918.html
Set EnableAutoDragDrop=false or your user will have 2 entries(1 duplicate) rather than just one entry. Eg. user picks"cat5" and when dropped in RichTextBox "cat5" appears twice.
Just a guess - maybe you missed to correctly set the drag'n'drop effect.
In WinForms I could handle the Validated event to do something after the user changed text in a TextBox. Unlike TextChanged, Validated didn't fire for every character change; it only fired when the user was done.
Is there anything in WPF I can use to get the same result, an event raised only after the user is done changing the text?
LostFocus will fire when the user moves from your textbox onto any other control.
It seems that there is no native solution.
The LostFocus event is a good idea. But when the user click on Enter, he wants the TextBox to validate the change.
So here is my suggestion : use the LostFocus event and the KeyDown event when the key is Enter.
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
// code to lauch after validation
}
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
// call the LostFocus event to validate the TextBox
((TextBox)sender).RaiseEvent(new RoutedEventArgs(TextBox.LostFocusEvent));
}
}
LostFocus is not equivalent to Validate. It creates lots of problem when you have multiple text boxes on one screen and every text box has some logic written in Validate. In validate event you can control focus easily but not in LostFocus so easily.
You can also try Binding.ValidationRules
Documented at : http://msdn.microsoft.com/en-us/library/system.windows.data.binding.validationrules.aspx
Here is the article to get started:
How to implement binding validations :
http://msdn.microsoft.com/en-us/library/ms753962.aspx