How to simulate keystroke in WPF, but outside the application? - c#

Currently I used this snip code as a result from googling.
var eventArgs = new TextCompositionEventArgs(Keyboard.PrimaryDevice,
new TextComposition(InputManager.Current, Keyboard.FocusedElement, "A"));
eventArgs.RoutedEvent = TextInputEvent;
var flag = InputManager.Current.ProcessInput(eventArgs);
It was working if I used Keyboard.Focus(TxtBox); and the TxtBox will be filled with the Keystroke.
But what I want really achieved is:
1.Drawing a box (for example, I draw box on one of the excel cell)
2.Click on the box coordinate (to change Keyboard Focus)
3.Send Keystroke to clicked excel cell
I have done step 1 and 2.
But I can't find a way to do the third step.
Somehow, the click event (using mouse event) maybe not changing Keyboard Focus automatically.
So, how do I change Keyboard focus, if possible using coordinate ?
Or maybe can I get IInputElement from a coordinate ? and then set keyboard focus to it.
Of course, all of it outside from the main application window of the WPF.

Found it !
At:
Installed InputSimulator via NuGet, no members accessible
It is working in most cases.
I said in most cases, because it is able to type in other window like excel application, but on other custom app window. There might be a case it won't work.
Hope it help for other people, looking for the same thing.

Related

How to set Word Application.Selection focused

I am building a Word VSTO Add-in. There I have a side drawer with some buttons on it. Now when I click on a button it inserts a predefined text in a document selection position. When it inserts the text I would like to bring back focus to the document itself.
How to do that?
My best try so far:
Word.Selection currentSelection = Application.Selection;
currentSelection.Text = ((Button)sender).Tag.ToString();
Application.ActiveWindow.SetFocus();
Application.ActiveWindow.Activate();
It makes sense to call the Activate method prior calling the SetFocus one:
Word.Selection currentSelection = Application.Selection;
currentSelection.Text = ((Button)sender).Tag.ToString();
Application.ActiveWindow.Activate();
Application.ActiveWindow.SetFocus();
Also you may find Windows API functions helpful for such scenarios. For example, the SetForegroundWindow function which brings the thread that created the specified window into the foreground and activates the window. Keyboard input is directed to the window, and various visual cues are changed for the user. You may find the Win32: Bring a window to top thread helpful.
Try Application.ActiveDocument.Activate.

Is it possible to disable a control but still receive events for that control?

In windows forms I have a simple TextBox:
TextBox textBox = new TextBox() { Text = "text" };
textBox.Enabled = false;
textBox.MouseEnter += (object sender, EventArgs e) =>
{
MessageBox.Show("MOUSE ENTERED"); // this never fires if the control is disabled.
};
I want to disable the users ability to interact with the control and I want the control to be styled as a disabled control. But I also want to receive MouseEnter,MouseLeave, and Click events from the control so that I can change the background cover of the control on hover and respond to clicks on the control.
But as I have just discovered if you disable a windows forms control it disabled the events as well. I know with some effort I can accomplish the same thing by checking mouse coordinates globally but it would be a lot nicer if I could just have it disabled but still receive events for it. Is that possible?
Enabled doesn't really do anything in Windows Forms itself. It is a property of windows controls in general that a disabled window doesn't receive input messages (such as mouse events and keyboard events). So no, there is no way for you to disable a control and still receive those messages. Windows just don't work that way on Windows. It's not the TextBox control filtering those messages away - they don't come in the first place.
TextBox is a great wrapper around a windows common control. When you do something like tbx.Text = "Hello";, the TextBox just sends a message to that common control, saying "change the text to Hello". If you want to change that, you need to make the control essentially from scratch. You can make some hack that reverts whatever the common control does as response to a mouse event, but these usually don't work very well and tend to break down in unexpected ways.
In practice, what you really want is probably to tweak either the way ReadOnly behaves (e.g. disabling focus as well as making the control read only, but that's again just a dirty hack), or replace the TextBox with a control that can either be a control or a label - allowing you to switch between the two. If you want the text box to stop behaving as a text box, stop it from being a text box. Problem solved :)
I'd still reconsider using ReadOnly, though. Are you sure the user would not want to select text in the text box and copy it somewhere else? Or change the reading order?

How to prevent auto closing of soft input panel in UWP?

I am facing an unexpected behavior of Keyboard showing and hiding in UWP app working on tablet with windows 10.
After carefully testing again and again i noticed that this issue comes when you have focus on input box and keyboard is opened for it. Now focusing next input needs layout adjustment so that it should not be hidden by keyboard. When you try to focus next element, by default previously opened keyboard hides and now i'm not able to open keyboard un till this new input box lose focus and manually gain focus again.
So for controlling this issue i want to prevent automatic hide and show of keyboard every time i switch focus to new textbox. It should open keyboard once the page load (already found solution using InputPane) and hiding should only be by clicking cancel (x) button.
Please check this video for clearly understanding the issue.
https://www.dropbox.com/s/1c876uwytywio1t/Soft%20Keyboard%20Issue.mp4?dl=0
Please vote this suggestion if anyone else is also facing this issue.
https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/34170142-inputpane-does-not-open-when-focus-is-shifted-to-n
This issue has been partially resolved in windows 10 version 1803 released on 30th April, 2018. In this version InputPane does not hide and show again and again when focus is shifted from one input element to other.
You may try to put a horizontal-stretched placeholder control (let say, StackPanel) at the bottom of your page, then let it the same size the on-screen keyboard does. That could prevent uncontrolled auto-hide trigger being fired (at least I did that trick on UWP mobile app):
// on the window initialization, remember the input pane
this._inputPane = InputPane.GetForCurrentView()
// then, subscribe to the events
_inputPane.Showing = (sender, args) =>
{
args.EnsuredFocusedElementInView = true; // skip default vertical-shift behavior
this._placeholderPane.Height = args.OccludedRect.Height;
}
_inputPane.Hiding = (sender, args) =>
{
this._placeholderPane.Height = 0;
}
Hope it helps on the Win10 desktop same way as it was on mobile one.
P.S. Yes, initially the placeholder pane is zero-height and collapsed.

Silverlight 4 - downloading data into tooltip w/ Bing Maps

I'm adding a syndication (RSS) feed into a Bing maps application where the data is downloaded and populated on a mouse over event. The download is super fast but of course it has to be downloaded asynchronously meaning the user won't see the tooltip populated until the next time they mouse over that tool tip. I know that, for security reasons, I shouldn't necessarily be able to emulate a mouse-over event, but I know there are other things like this where there is a workaround (for example, if a user is logging in and enters their username and password - there's a workaround so that they can press 'ENTER' without the Login/Submit button having focus).
So first I'm wondering if there's a workaround and, if not...is there an easier way to do this than emulating a synchronous download via coroutines (worth noting: MVVM can not be used here due to the way the nature of the model - Also, each pin has its own tool tip rather than a single custom tool tip where the position would be determined on mouse over via MapLayer.SetPosition)
Thanks!
figured it out - just attach a boolean property on the mouse enter event and to make sure the mouse is still over the element providing the tool tip - on mouse enter set the mouse leave bool to false and the tool tip's IsOpen property to false. When the download has completed - bind your DataContext to the object with relevant data (or however you want to go about this) then, if mouse leave bool is still equal to false, set the IsOpen property = true

WPF TextBox doesn't take input, space and backspace works

I have textbox inside a usercontrol and I add the usercontrol to the MainWindow with the following XAML:
<Views:MyUserControl />
I have one TextBox in MyUserControl, the problem is that the TextBox doesn't take any input. Backspace och space works, but if I press the letter och numbers no text is added to the TextBox.
I have made sure that the text is not just hidden in the TextBox.
I have also tried to add a RichTextBox to MyUserControl with the same result, it doens't take any input (beside space och backspace).
I have also tried to add a TextBox to the MainWindow with the same result; it doens't take any input (beside space och backspace).
Also MyUserControl is added in a TabControl and TabItem.
Any clues?
Edit: Additional information
Forgot to write that I'm opening/creating the WPF Window from a WinForm application.
When I set my startup project in VS10 to be my WPF-project it work great with the keyboard input to the TextBox.
How come?
Im opening/creating my WPF windows with the following code:
MyWpfProject.MainWindow mw = new MyWpfProject.MainWindow();
mw.Show();
Edit: Solution
So I guess my real problem was that is was opening the WPf project from a WinForms application.
I added the following code:
MyWpfProject.MainWindow mw = new MyWpfProject.MainWindow();
ElementHost.EnableModelessKeyboardInterop(mw);
mw.Show();
"The EnableModelessKeyboardInterop() call is necessary to handle keyboard input in the WPF window if loaded from a non-WPF host like WinForms."
http://weblogs.asp.net/jdanforth/archive/2008/07/29/open-a-wpf-window-from-winforms.aspx
Answer to my own question (if someone else run into the same problem):
If you open a WPF-form from a WinForms application you have to do the following to get keyboard input:
MyWpfProject.MainWindow mw = new MyWpfProject.MainWindow();
ElementHost.EnableModelessKeyboardInterop(mw);
mw.Show();
"The EnableModelessKeyboardInterop() call is necessary to handle keyboard input in the WPF window if loaded from a non-WPF host like WinForms." http://weblogs.asp.net/jdanforth/archive/2008/07/29/open-a-wpf-window-from-winforms.aspx
maybe your user control is getting the keyboard event instead of your textbox? try to search in this way, it happens with mouse buttons.
I had the same problem but my Environment was built such that I could not apply the solution above. As it turned out that wasn't the problem. It was much more easier than expected.
I host a WPF User Control inside WinForms. My WinForms MainView (Startup form) did override the "ProcessCmdKey". Because of logical errors it returned nothing.
Nevertheless I received all key events in code behind in my XAML file but this events never updated the "Text" of my text box. Only space and backwards did so and this were the key events I didn't receive in code behind.
So in case you don't think of the simplest solution here it is for VB.NET.
STRG+F "ProcessCmdKey" and make sure that you Return the correct value of you may completely uncomment it just to verify that it isn't causing you the same trouble as it did to me.
I would like to add my own answer just on the off chance it can help anyone else with the same or similar problems. My particular use case was a .Net windows form created by an addin. The addin was running out of Autodesk Inventor which I think may be WPF (but don't take my word for it.) The addin had several windows forms some docked within the application and with some acting as popups or a separate secondary window. The solution was to set the windows forms owner to one of the docked forms. Doing this allowed text to be edited and entered into its textboxes. Very niche solution to a niche problem but hopefully it may help someone at some point in the future.
private void CreatePanels(DockableWindows DockableWindows)
{
//Create the dockable window that the panel form will live on.
DockableWindow SideWindow =
DockableWindows.Add(SidePanelNames.GUID, SidePanelNames.InternalWindowName, SidePanelNames.Title);
//Configure the windows settings.
SideWindow.ShowTitleBar = true;
SideWindow.ShowVisibilityCheckBox = true;
SideWindow.DisableCloseButton = false;
SideWindow.Visible = true;
SideWindow.AddChild(SidePanel.Handle); //Add the forms as children and then display to the user.
SidePanel.Show(); //Display the panel to the user.
}
/// <summary>
/// Creates the Display window were order and patient information is displayed to the user.
/// This method makes the adjust device form the owner of the display window. Because of this
/// dependecency it should be run after the panels have been created.
/// </summary>
private void CreateDisplayWindow()
{
DisplayForm = new DisplayForm //Create the display form.
{
Owner = SidePanel //Doing this allows text boxes to have values entered into them.
};
DisplayForm.Show(); //Show the display form to the user.
}
//Adding the side side panel as the owner of the display form was effectively the only change I needed to make.
I will add a few words of warning for anyone attempting this solution. Simply put I've since found out it's not great. It prevents the form or any of its controls from detecting certain key presses (enter and tab) which matters a lot for my usage. You'll find a much better and solution here https://forums.autodesk.com/t5/inventor-forum/dockable-window-with-wpf-controls-don-t-receive-keyboard-input/td-p/9115997

Categories

Resources