Is there any way to disable tab indexing for whole app (all controls) in WPF using KeyboardNavigation.TabNavigation?
Another potentially safer approach would be to handle the PreviewKeyDown event of the window programmatically:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
PreviewKeyDown += (s, e) =>
{
e.Handled = e.Key == Key.Tab;
};
}
}
I think I found solution. Placing KeyboardNavigation.TabNavigation="None" on header section inside MainWindow.xaml solved it
Related
Does XAML provide a way to detect if the user's mouse cursor has left the Silverlight window? If so, how would I go about doing this?
Thanks for your help.
Yes there is.
Assuming the the MainPage is your RootVisual and you've added a reference for System.Windows.Browser assembly then the following code should work.
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
//objSilverlight is the <object> tag id
var element = HtmlPage.Document.GetElementById("objSilverlight");
element.AttachEvent("onmouseout", new EventHandler(HandleMouseOut));
}
public void HandleMouseOut(object sender, EventArgs args)
{
//handle your event here
}
}
Basically the .Net event handler is being attached to the onmouseout DOM event in the Html object element that contains the silverlight plugin.
I have am making a map editor for a game which has a user control that has an image. Inside that control I attached the MouseWheel event to it, but I've noticed two issues that I hope to have a better understanding of why it behaves the way it does and how to properly implement it.
For one the event only seems to fire when the mouse is hovering over it instead of when the control is in focus. If possible I would like to switch that and be able to fire the event no matter where the mouse is as long as that control is in focus and the second issue is that checking the delta when the number is positive works fine, but when I get a number back when it's negative I get a value of 0xfffffffd or something in that range. How would I go about differentiating the difference between a positive balue and a negative value if I always get something positive?
Thanks in advance for the help.
If you want to fire MouseWheel event for focused element try:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.MouseWheel += OnMouseWheel;
}
IInputElement focusedElement;
private void OnMouseWheel(object sender, MouseWheelEventArgs e)
{
if (focusedElement is TextBox)
{
var tbx = focusedElement as TextBox;
//do something
}
}
protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
focusedElement = e.NewFocus;
}
}
I have WPF control hosted inside a WinForms control using ElementHost. The WinForms control has a context menu. I want to show the context menu when user right click on the WPF control. How can this be done? It seems mouse event is not bubbled from WPF to WinForms.
it is not automatically bubbled up, as you might have handled it in the WPF control in the first place. However, you can easily add this yourself.
In your WPF user control, expose an event that you trigger on right mouse up:
public event Action ShowContext;
private void rectangle1_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
if (ShowContext != null)
{
ShowContext();
}
}
Then in your winforms control with element host you can use it like so:
public UserControl1 WpfControl { get; set; }
public Form1()
{
InitializeComponent();
WpfControl = new UserControl1();
WpfControl.ShowContext += () => contextMenuStrip1.Show(Cursor.Position);
elementHost1.Child = WpfControl;
....
I'd like the main menu in my WPF app to behave like the main menu in IE8:
it's not visible when the app starts
pressing and releasing Alt makes it visible
pressing and releasing Alt again makes it invisible again
repeat until bored
How can I do this? Does it have to be code?
Added in response to answers submitted, because I'm still having trouble:
My Shell code-behind now looks like this:
public partial class Shell : Window
{
public static readonly DependencyProperty IsMainMenuVisibleProperty;
static Shell()
{
FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
metadata.DefaultValue = false;
IsMainMenuVisibleProperty = DependencyProperty.Register(
"IsMainMenuVisible", typeof(bool), typeof(Shell), metadata);
}
public Shell()
{
InitializeComponent();
this.PreviewKeyUp += new KeyEventHandler(Shell_PreviewKeyUp);
}
void Shell_PreviewKeyUp(object sender, KeyEventArgs e)
{
if (e.SystemKey == Key.LeftAlt || e.SystemKey == Key.RightAlt)
{
if (IsMainMenuVisible == true)
IsMainMenuVisible = false;
else
IsMainMenuVisible = true;
}
}
public bool IsMainMenuVisible
{
get { return (bool)GetValue(IsMainMenuVisibleProperty); }
set { SetValue(IsMainMenuVisibleProperty, value); }
}
}
You can use the PreviewKeyDown event on the window. To detect the Alt key you will need to check the SystemKey property of the KeyEventArgs, as opposed to the Key property which you normally use for most other keys.
You can use this event to set a bool value which has been declared as a DependencyProperty in the windows code behind.
The menu's Visibility property can then be bound to this property using the BooleanToVisibilityConverter.
<Menu
Visibility={Binding Path=IsMenuVisibile,
RelativeSource={RelativeSource AncestorType=Window},
Converter={StaticResource BooleanToVisibilityConverter}}
/>
I just came across this problem myself. I tried hooking into the PreviewKeyDown event, but found it to be unreliable. Instead I found the InputManager class where you can hook into the EnterMenuMode from managed code. The manager exposes two events, for enter and exit. The trick is to not collapse the menu, but set it's container height to zero when it is to be hidden. To show it, simply clear the local value and it will take its previous height.
From my TopMenu user control:
public TopMenu()
{
InitializeComponent();
InputManager.Current.EnterMenuMode += OnEnterMenuMode;
InputManager.Current.LeaveMenuMode += OnLeaveMenuMode;
Height = 0;
}
private void OnLeaveMenuMode(object sender, System.EventArgs e)
{
Height = 0;
}
private void OnEnterMenuMode(object sender, System.EventArgs e)
{
ClearValue(HeightProperty);
}
I'd try looking into handling the PreviewKeyDown event on your window. I'm not sure if pressing Alt triggers this event or not, but if it does, then I'd toggle a bool which is bound to the visibility of the main menu of the window.
If PreviewKeyDown doesn't work, I'm not sure what else to try. You could look into getting at the actual Windows messages sent to your window, but that could get messy very quickly.
It would be better to use GetKeyboardState with VK_MENU to handle both left and right Alt, to mimic the behavior of IE / Windows Explorer (Vista+) you'll need to track the previously focused element to store focus, on a VK_MENU press whilst the focused element is within your main menu. You also want to be doing this work on PreviewKeyUp (not down).
See my answer to the following thread:
How to make WPF MenuBar visibile when ALT-key is pressed?
There I describe how to solve your problem with the class InputManager (from namespace System.Windows.Input).
You can register the classes events EnterMenuMode and LeaveMenuMode.
I'm writing an app that uses the "tabbed browsing" metaphor, with a TabControl the full size of the window, and other stuff inside the tabs. Sometimes those tabs will themselves contain other TabControls.
(Tabs inside tabs can be confusing, so I'll re-style the inner TabControl so it doesn't look like a TabControl. I'll probably style it to use ToggleButtons at the top instead of tabs.)
I want this UI to behave like you would expect the tabbed-browsing metaphor to work: Ctrl+Tab should always switch tabs on the outer TabControl (the one that looks like a TabControl), even if keyboard focus is inside the inner TabControl (which doesn't look like a TabControl, and therefore shouldn't be expected to respond to Ctrl+Tab). But, of course, the inner TabControl gets the key event first and handles it itself.
What's the best way to keep the inner TabControl from responding to the Ctrl+Tab and Ctrl+Shift+Tab key events, so those events can bubble up to the outer TabControl?
The WPF TabControl appears to manage the keyboard navigation feature via the OnKeyDown method. I would suggest creating a custom control that inherits from the TabControl, and override the OnKeyDown method.
You can handle the PreviewKeyDown event on your inner TabControl and set e.Handled = true to prevent it from handling key events. You can then find the parent TabControl (perhaps recursively through ((TabControl)sender).Parent ) and change its SelectedIndex programmatically.
Wrapping that up in a custom control would keep it reasonably clean.
As an alternative to creating a Custom Control as suggested here, you could create an "Attached behaviour" to encapsulate this:
namespace WpfApplication1
{
using System.Windows;
using System.Windows.Input;
public static class IgnoreCtrlTabBehaviour
{
//Setter for use in XAML: this "enables" this behaviour
public static void SetEnabled(DependencyObject depObj, bool value)
{
depObj.SetValue(EnabledProperty, value);
}
public static readonly DependencyProperty EnabledProperty =
DependencyProperty.RegisterAttached("Enabled", typeof(bool),
typeof(IgnoreCtrlTabBehaviour),
new FrameworkPropertyMetadata(false, OnEnabledSet));
static void OnEnabledSet(DependencyObject depObj, DependencyPropertyChangedEventArgs args)
{
var uiElement = depObj as UIElement;
uiElement.PreviewKeyDown +=
(object _, System.Windows.Input.KeyEventArgs e) =>
{
if (e.Key == Key.Tab &&
(Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
e.Handled = true;
}
};
}
}
}
Use in XAML like this:
<Window x:Class="WpfApplication1.MainWindow"
...
xmlns:local="clr-namespace:WpfApplication1"
...
<TabControl local:IgnoreCtrlTabBehaviour.Enabled="True">
<TabItem Header="tab1">
...