Programmatically calling PreviewTextInput not invoking TextChanged event - c#

I have a TextBox that only allows certain characters to be typed into it; I'm handling this logic in the PreviewTextInput event. If it's a character that's allowed, then the TextChanged event is fired, otherwise it cancels the TextChanged event.
I have another application that is opened on a second screen while this is running, however even if there is keyboard input while the other application is active, it should still update the currently focused TextBox on the main application. To do this, I added a listener to the OnKeyPress() event on the second application, which calls the PreviewTextInput event on the focused TextBox in the main application.
Here is the code:
private void ImageEventController_OnKeyPress(char c)
{
object focusedElement = this.CurrentKeyboardFocus;
if (focusedElement != null)
{
if (focusedElement is TextBox)
{
TextBox target = (TextBox)focusedElement;
if (target.IsEnabled)
{
string text = c.ToString();
var routedEvent = TextCompositionManager.PreviewTextInputEvent;
target.RaiseEvent(new TextCompositionEventArgs(
InputManager.Current.PrimaryKeyboardDevice,
new TextComposition(InputManager.Current, target, text)) { RoutedEvent = routedEvent });
}
}
}
}
When this is called, it goes through the PreviewTextInput event, however the TextChanged event never gets fired even if it's a valid character. Is there any reason why TextChanged is not getting fired when PreviewTextInput is invoked programmatically?
UPDATE:
I added in this code to the bottom of my PreviewTextInput event listener:
if (!e.Handled)
{
textbox.Text = e.Text;
}
This forces the TextChanged event to fire and fixes the functionality when the second application has focus, however if the main application has focus it causes two TextBoxes to get updated when only pressing one button.

I was unable to figure out how to invoke the TextChanged event from PreviewTextInput, but I did manage to accomplish what I needed to do:
Instead of performing the logic to validate the key pressed is valid inside of the PreviewTextInput event, I pulled all of the logic out and put it into a public function. Then in my ImageEventController_OnKeyPress event I am using the LogicalTreeHelper.GetParent() method to find the necessary control. From there I call the public function to validate a valid key is pressed and if it is, I call the TextInput directly.

Related

Window.Current.CoreWindow KeyDown Event won't fire for "Tab" key Pressed in c#?

what I have Tried is ?
Window.Current.CoreWindow.KeyDown += keydown;
private void keydown(CoreWindow sender, KeyEventArgs args)
{
//Printing entered key
}
I'm developing UWP application.In my app Window.Current.CoreWindow
keydown event fired for all the keys in keyboard except "Tab" key.
I don't know why the event don't fire for that specific key?I want to do some actions while "Tab" key is pressed. Anyone know, how to fire the event when "Tab" key is pressed ?
By testing, sometimes pressing Tab key will not trigger CoreWindow.KeyDown event handler when there are some controls such as Button can get focus in a page. You could try to add a UIElement.KeyDown event or a UIElement.PreviewKeyDown event to a page(such as MainPage) in xaml file.
Update:
When you use CoreWindow.KeyDown event and there are controls which could get focus in your page, pressing Tab key will let the focus step into a tab sequence instead of triggering the CoreWindow.KeyDown event. The CoreWindow.KeyDown event could be triggered when Tab key is pressed and the focus locates at the last control which could get focus.
If you want CoreWindow.KeyDown event to be triggered when Tab key is pressed, you could set TabNavigation as Once in your page. If you want save the Tab key’s feature that stepping into tab sequence, we still suggest you use UIElement.KeyDown event or UIElement.PreviewKeyDown event.
For example:
Window.Current.Content.KeyDown += Content_KeyDown;
Update:
Window.Current.Content.KeyDown event is a routed event. About routed event, you could refer to the document. A routed event is an event that is potentially passed on (routed) from a child object to each of its successive parent objects in an object tree.
In your scenario, you could monitor the value of e.OriginalSource and you could view that when you step into the last control which could get focus by pressing Tab key the KeyDown event will be triggered twice. In the second trigger, the value of e.OriginalSource could be Windows.UI.Xaml.Controls.Frame( may be different, subject to your observation in the second trigger). That’s because the routed KeyDown event need to bubble to its parent object at this time. You could add some code to identify the second trigger.
For example:
private void Content_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.OriginalSource.ToString()!= "Windows.UI.Xaml.Controls.Frame")
{
//Just be fired once here
}
}
Note, you could try to use code e.Handled = true; to stop the routed behavior referring to here. And, if you use Page.KeyDown event, there is no situation that KeyDown event be triggered twice.

keyUp event not working [WinForm]

I have got some controls on the Panel and I am trying to delete them using "Delete" button. I handled KeyPress Event as mentioned in How to get Keypress event in Windows Panel control
Your issue is that the event MainForm_KeyUp does not even get fired on your key up, because you have focues another control. But you can fix that with KeyPreview.
A Form object has the property KeyPreview. According to the MSDN:
Gets or sets a value indicating whether the form will receive key events before the event is passed to the control that has focus.
So when you set:
this.KeyPreview = true;
You enable that your MainForm gets notified about those key events always. Even when any other Control is focused. So you enable that those key events will invoke MainForm_KeyUp().
Now set a breakpoint:
private void MainForm_KeyUp(object sender, KeyEventArgs e)
{
//set a breakpoint here, so you get confirmation, that the event will get fired
//on key up of the *delete* button
//...now do what you desire
}

Is there a way to clear a TextBox's text without TextChanged firing?

In my application I'd like to handle TextBox input in certain cases (some criteria is not filled, for example) and because KeyDown is useful only for keyboard input but not actual pasting from the clipboard (I wouldn't want to go through the trouble of doing that using Win32 calls anyway), I figured I'd just handle everything in my primary TextBox's TextChanged event. However, when there is something "wrong" and the user should not be able to type in it, if I am to call TextBox.Clear(); on it, TextChanged fires a second time, understandably, so the message gets displayed two times, as well. That's kind of annoying. Any way I can handle TextChanged only in this case? Sample code (inside txtMyText_TextChanged) :
if (txtMyOtherText.Text == string.Empty)
{
MessageBox.Show("The other text field should not be empty.");
txtMyText.Clear(); // This fires the TextChanged event a second time, which I don't want.
return;
}
What about to disconnect the event handler before the change and reconnect afterward?
if (txtMyOtherText.Text == string.Empty)
{
MessageBox.Show("The other text field should not be empty.");
txtMyText.TextChanged -= textMyText_TextChanged;
txtMyText.Clear();
txtMyText.TextChanged += textMyText_TextChanged;
return;
}
In more complex cases it is better to have a try/finally and reenable the TextChanged event in the finally part

how to launch event from a textbox even when the field is empty c# wpf

I get data from the data base then i show it in a datagrid (wpf) , the user can make quick search (filter) from a textbox after clicking on Enter.
I use this event to handle the button -Enter- click
(OnSearch - This event is spawn whenever the search button is clicked or the Enter key is pressed.)
the problem is when the user don't write anything, the event will not be launched even when he click on Enter-Button !
how can i proceed to make it work
public MainWindow()
{
InitializeComponent();
//m_txtTest is a SearchTextBox
m_txtTest.OnSearch += new RoutedEventHandler(m_txtTest_OnSearch);
}
void m_txtTest_OnSearch(object sender, RoutedEventArgs e)
{
//to get the entered string
SearchEventArgs searchArgs = e as SearchEventArgs;
....
....
....
....
}
So when your user types something in and presses enter it is the textbox handling the Event.
When they don't type anything though the textbox doesn't have focus and cant handle the event.
What I would do is create an event for searching on the window or grid.
Somthing like this
this.OnPreviewKeyDown += new OnPreviewKeyDownEvent;
http://msdn.microsoft.com/en-us/library/ms748948.aspx
You can think of it like this
Window has focus
->Grid has focus
-->textbox has focus
What ever the last thing that has focus (or the most inner element, think of it like a cake) is will be the thing that sees the event first. If you have that event registered for that UI element it will handle it.
The textbox isn't focused so it wont see the event

Code for Numericupdownextender event handler

i want to change image of an image control based on the value of textbox by clicking on the ajax numericupdownextender control.Please provide solution in c# and also tell me how we can write custom code for this.
I imagine you'll want to use the currentChanged event of the NumericUpDownExtender. This fires an event client side (in javascript - not C#).
"The NumericUpDown extender has only one event, currentChanged. This event is fired whenever the value of the extended textbox is changed through the up/down buttons or when the user types a new value in that textbox. In case of typing, the event fires whenever the focus leaves the textbox."
function pageLoad(sender, args) {
$find('<%= NumericUpDownExtenderID.ClientID %>').add_currentChanged(methodtocall);
}
function methodtocall(sender, e) {
alert(String.format('change event fired. Value: {0}', e));
}
If this doesn't solve your problem then you need to be clearer in your question.

Categories