I have an application using cefSharp and some KeyGestures to open some forms. We were initially using the WPF ChromiumWebBrowser, but required the use of touch scrolling, which is not supported. As a result, we changed the control to the WinForms ChromiumWebBrowser inside a WindowsFormHost.
After the switch, KeyGestures bound to our RoutedCommands no longer fire.
After reviewing here, here, and here, I have tried several different solutions, but to no avail.
As per the above, when the window is deactivated, then activated the KeyGestures are routed appropriately (as discussed regarding breakpoints 'causing' the commands to work).
I have tried using the CommandManager.InvalidateRequerySuggested method on a timer or being called on loaded, after transfering focus to the window, after transfering forcus to another WPF control and after focusing the WindowsFormsHosts.
My command declaration is as follows:
RoutedCommand ShowAdmin = new RoutedCommand();
ShowAdmin.InputGestures.Add(new KeyGesture(Key.F1, ModifierKeys.Shift | ModifierKeys.Alt | ModifierKeys.Control));
CommandBindings.Add(new CommandBinding(ShowAdmin, ShowAdminForm));
I essentially have two questions:
1) Why am I not receiving the command. Is it because the WinForms control doesn't 'bubble' the keypress events?
2) What can I do to capture the keygesture without resorting to opening another window, only to close it again
Thanks in advance for your questions, comments and answers!
If you implement IKeyboardHandler you should be handle custom key press combinations, that's probably your easiest and cleanest solution.
https://github.com/cefsharp/CefSharp/blob/master/CefSharp/IKeyboardHandler.cs
Related
we have a WPF component (User Control) that's hosted in a Win Form through ElementHost. the WPF component is defined as the ElementHost's Child through
ElementHostControl.Child = wpfFrame
there are certain key bindings we want to pass in from the Win Form to WPF form. we are doing so through KeyBinding(). then we assign the keybinding to the
WPFFrame.InputBindings.add(curBinding);
it's kind working with most key combinations although I didn't test all of them. but Ctrl+B, Shift+P etc. seems all working fine.
But I try Shift+(Left Arrow key), it's not working. what's interesting is when I try it in standalone WPF application then it's doing the job as expected.
I made sure the data flow through the exactly same code but why Shift+P works while Shift+ <- doesn't? now I set a breakpoint in the WPF Commend executed and run it from Win Form. I use key binding to trigger another command then use Ctrl+<- to trigger the problematic command it actually "sometimes" working. if I remove breakpoint and do Ctrl+<- then it never triggers the associated command.
I suspect it's an integration issue in between WPF and Win form since Shift+<- works in WPF itself.
any input is appreciated.
it's indeed a focusing issue. setting a break point and this line:
var v = Keyboard.FocusedElement;
at runtime shows the focus was stolen by various elements. I need to hand pick couple of them and set
Focusable="False"
in XAML. issue fixed!
I am trying to create a simple onscreen keypad created using buttons (currently a User-control), on those buttons i have a click event, when i click/touch a button i want the value of that button sent to a Text-block in my Main-window.
I can't/don't understand how to make the User-control (keypad) see the Text-block (in Main-window) to add in the value that i need.
I have seen solutions that use command Bindings and solutions that use the visual tree traversing but all of them are the main window accessing the user control, not the other way around.
All the examples are the other way around because that is how a UserControl is supposed to work.
A UserControl is a packaged piece of re-usable functionality. It should not know anything about the code that is using it.
Instead you should expose routed events in your UserControl for things like a when number was selected, and subscribe to them in your main window.
There are many ways to achieve what you want. If your MainWindow.xaml has a UserControl and you want to react to a change from the control in the MainWindow.xaml.cs file, then you could add a delegate to the UserControl code behind and register a handler for it in the MainWindow.xaml.cs file. Implementing new delegates are generally somewhat simpler than implementing RoutedEvents, which is another way that you could handle this situation.
Using a delegate like this will enable you to effectively pass a signal to the main view from the child UserControl code behind, which you can react to in any way you want to. Rather than explain the whole story again here, please see my answers from the Passing parameters between viewmodels and How to call functions in a main view model from other view models? posts here on Stack Overflow for full details on how to achieve this.
So I followed the guide on the following site to restrict the characters a textbox can accept.
http://www.rhyous.com/2010/06/18/how-to-limit-or-prevent-characters-in-a-textbox-in-csharp/
My problem is I can't figure out how to make the event handler trigger in the secondary class. Basically how do I tell VS to look for the event handler code in that class instead of MainWindow? I tried searching, but apparently don't know the correct terms to use. The xaml reference I used was
xmlns:DigitBox="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"
Any ideas?
Simplest way I've found to do it is assign the event in your constructor.
public MainWindow()
{
InitializeComponent();
TextBoxCurrency.GotFocus += expandedTextBoxEvents.TextBoxCurrencyGotFocus;
TextBoxCurrency.LostFocus += expandedTextBoxEvents.TextBoxCurrencyLostFocus;
}
I've searched a way to do it in XAML and I did not found an easy and clean way to do it.
You are much better off using commands and command bindings. I'm not sure what the specific command that would would bind to for a text box for your desired functionality, but one of the goals for WPF was to lessen the use of Event Handlers in code behind.
Check out this article for an overview of commands and this article for a way to hook up commands with events. WPF commanding is one of the coolest features to enable true separation of concerns between UI and business logic.
As a worst case scenario solution, you could create your own text box that inherits from the text box control and hook up the events in that class. Your control would then be reusable.
I'm designing a custom form in a WPF ResourceDictionary using a controltemplate so I can easily use the window later on. I'm designing it with Expression Blend and I'm stuck on getting the close, maximize and minimize buttons to work.
At first I wasn't able to access any of the events, however this stackoverflow question helped me with binding a class to the resourcedictionary. When I try to access the click event for the close, min and max buttons, I get in the code editor and the btn_Close eventhandler shows up.
When I try to compile it gives me the error "application.Resources doesn't contain a defition for close (...)" (Resources is the name of the class)
(when I type "this." intellisense gives me many commands but not .Close)
I'm pretty sure all of the namespaces in both the class and XAML are right, how do I get this working properly? Or do I need to code this seperately for each form that uses this template?
In the strange situation you've arranged, this in the code-behind does not refer to a Window but to the ResourceDictionary. Nevertheless, the event when it occurs will be generated by a window so instead of using this you need to cast the sender parameter to a Window and Close that instead.
I have a c++ windows app calling into a c++/cli library, which is calling into a managed library. The managed library is calling OpenFileDialog.Show with a WPF window parent which is owned by the Win32 window. I haven't found a better way to do this, and all the resources I've read here and searching google and social.msdn recommend doing what I'm doing.
The dialog opens just fine, but when I hit the cancel button, for instance, the app loses focus completely. I'm not sure why it's happening, but I can't seem to make it stop. I've tried a number of different things to no avail.
If I just launch the OpenFileDialog without creating a WPF Window, I don't see the problem.
If I don't set the owner of the WPF Window, I don't see the problem. If I call OpenFileDialog.Show and don't pass the parent, but still create the WPF Window and set its owner, I still see the problem.
I am able to hack it to set the parent app window to foreground after it loses focus, but I would like to not have to.
I have uploaded a small example solution for my scenario that illustrates the problem:
http://dl.dropbox.com/u/26054523/MixedExample.zip
Any help would be appreciated.
Have you tried inverting the hosting scenario? Right now it sounds like you're going unmanaged->bridge->managed->WPF->Winforms. Maybe you could go ...managed->WinForms->WPF using ElementHost http://msdn.microsoft.com/en-us/library/ms742215.aspx
In that way, the WPF window would just be a child control of the WinForms app and that might work out better for focus switches. WinForms controls are not really meant to work directly with WPF apps so well, two different UI threading setups are being used as you've noted.
I know that this is an old post but I think that this is a common problem and I have a good answer. If you have a Win32 window parent window called ParentWindow and a WPF child window called WPFChild you can do this:
using System.Windows.Interop;
void OpenWindow()
{
WPFChildWindow WPFChild = new WPFChildWindow();
WindowInteropHelper helper = new WindowInteropHelper(WPFChild)
{
Owner = new NativeWindowWrapper(ParentWindow.Hwnd).Handle
};
bool? ret = _stepsForm.ShowDialog();
}
This will cause the child window to remain on top of the parent and function as a dialog. Keep in mind that the WPF window does not return a DialogResult but rather a nullable bool.
NativeWindow wrapper is a simple class that takes casts an int as an IntPtr. It's actually from a .net Excel ref edit project located here: How to code a .NET RefEdit ControlT