I want to disable all default shortcuts in WPF TextBox. Shortcuts like Ctrl + A, Ctrl + V, Ctrl + C etc. Can this be done?. It looks to me that these shortcuts are executed before KeyDown event
You can intercept the keystrokes in the PreviewKeyDown event. Set the e.Handled member to true and that will prevent the actually processing of the keys.
public Window1()
{
InitializeComponent();
CommandManager.AddPreviewCanExecuteHandler(_textBox, _canExecute);
}
private void _canExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
e.Handled = true;
}
The above will prevent the TextBox from saying it can handle any command. You can selectively choose which commands you want to disable by examining the EventArgs. Or you can do this in XAML:
<TextBox x:Name="_textBox">
<TextBox.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy" CanExecute="_canExecute"/>
</TextBox.CommandBindings>
</TextBox>
Here we're just disabling the execution of the Copy command. Control-C won't work, nor will the context menu or main menu. In fact, any control that executes the Copy command will be disabled if the focus is in the TextBox.
Related
I'm designing a windows Phone app. I have a Hyperlink object in a RichTextBox, in a Grid. The Grid had a Tap event, and the Hyperlink has a Click event.
Clicking the Hyperlink also raises the parent Grid's Tap event. How can I prevent this?
I would use e.Handled in the Click handler, but RoutedEventArgs do not have a Handled property in Silverlight for Windows Phone... I also tried walking the logical tree to look for the original source, but the click appears to originate from a MS.Internal.RichTextBoxView control (e.OriginalSource)...
I don't think there is any good way from within the Click handler itself. The following state management can work though:
XAML:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" Tap="ContentPanel_Tap_1">
<RichTextBox Tap="RichTextBox_Tap_1">
<Paragraph>
fdsfdfdf
<Hyperlink Click="Hyperlink_Click_1">fdsfdsfsaf</Hyperlink>
fsdfsdfa
</Paragraph>
</RichTextBox>
</Grid>
and the code:
bool RtbTapHandled = false;
private void Hyperlink_Click_1(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Hyperlink");
RtbTapHandled = true;
}
private void RichTextBox_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
if (RtbTapHandled)
{
e.Handled = true;
}
RtbTapHandled = false;
System.Diagnostics.Debug.WriteLine("RTB_Tap");
}
private void ContentPanel_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Content_Tap");
}
In this case if you click on the RichTextBox you'll get callbacks from both RichTextBox_Tap_1 and ContentPanel_Tap_1, but if you click on the Hyperlink you'll get Hyperlink_Click_1 and RichTextBox_Tap_1 though it'll be handled at that level and stopped.
I have a reportViewer with default toolbar button for decrease zoom binded to command NavigationCommands.DecreaseZoom. I want to disable it in some situation so i bind CanExecute method to return false for that command which works perfectly fine and disable the button as expected. But, still zoom out works if i use shortcut key "Ctrl + Subtract key". I tried to set KeyBinding to the same command assuming CanExecute will work but it doesn't. Since, CanExecute is not provided in KeyBinding. Can someone suggest how can i disable KeyGesture "Ctrl -" for some situation(logic in CanExecute) and not permanently.
Relevant code -
<DocumentViewer Name="documentViewer1"
Margin="0,0,0,30"
Style="{DynamicResource DocumentViewerStyle1}">
<DocumentViewer.CommandBindings>
<CommandBinding Command="NavigationCommands.DecreaseZoom"
CanExecute="DecreaseZoom_CanExecute" />
</DocumentViewer.CommandBindings>
<DocumentViewer.InputBindings>
<KeyBinding Command="NavigationCommands.DecreaseZoom"
Key="OemMinus"
Modifiers="Control" />
</DocumentViewer.InputBindings>
</DocumentViewer>
Code behind -
private void DecreaseZoom_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (((DocumentViewer)e.Source).PageViews.Count >= 3)
{
e.CanExecute = false;
e.ContinueRouting = false;
e.Handled = true;
}
}
You can either create your custom command for this or you can create your own InputGesture, and override its behavior,
<KeyBinding.Gesture>
<CustomInputGesture/>
</KeyBinding.Gesture>
I solved my problem extending DocumentViewer and overriding method OnDecreaseZoomCommand. I tried using Custom Command but its event handler is not getting hit in case i use shortcut key "Ctrl -". But this works for me -
public class ExtendedDocumentViewer : DocumentViewer
{
protected override void OnDecreaseZoomCommand()
{
if (PageViews.Count < 3)
{
base.OnDecreaseZoomCommand();
}
}
}
WPF form must fall down in the task bar.. But I dont know do that?
+-x
x ---> Close the form
- ---> down the form taskbar?
You can use the closing event of the WPF Window to cancel closing and minimize it instead:
XAML:
<Window ... Closing="Window_Closing">
Code behind:
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
this.WindowState = WindowState.Minimized;
}
But you have to be aware that this also prevents other ways of closing the window, e.g. Alt+F4, "Close Window" from the toolbar etc.
You may checkout the WPF NotifyIcon control.
I have a window containing a textBox.
On both the window AND the textBox, I add a PreviewMouseDoubleClicHandler.
Handler in the window:
private void PreviewMouseDoubleClickHandler(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("handler in the window");
e.Handled = true;
}
handler in the textBox:
private void PreviewMouseDoubleClickHandler(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("handler in the textBox");
e.Handled = true;
}
now, when I double-click on the textBox, I expect to go first into the window's Handler, print the debug line, then handle the event, then nothing more. I thought the textBox's handler would not fire since the event has already been handled by the window.
This does not work like this though: I get both handlers fired.
The weird thing is: It works fine with the PreviewMouseDown event. If I do exactly the same thing but with PreviewMouseDownEvents, I get the behavior I expect, i.e.: the window handles the mouseDown and the textBox's handler is not fired.
so Why does this not work with the doubleClick event? Am I doing something wrong? Is it supposed to work like this? is the doubleClick Event managed in a different way that prevents me from using the advantages of tunneling?
The behavior is by design, please see: http://msdn.microsoft.com/en-us/library/system.windows.controls.control.previewmousedoubleclick.aspx
Snoop shows that the command is "ApplySingleSpace", but when I try disabling it via the method described in this article . Like this:
<RichTextBox.CommandBindings>
<CommandBinding
Command="ApplySingleSpace"
CanExecute="BlockTheCommand"/>
</RichTextBox.CommandBindings>
.
private void BlockTheCommand(object sender,
CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
e.Handled = true;
}
My app crashes because there is no ApplySingleSpace command. ApplySingleSpace is not in the EditingCommands either.
What am I missing?
Unfortunately that will not work for
me. The reason I am trying to disable
the command is that I have a
KeyBinding in a higher nested view
that is not firing because the CTRL+1
gesture is being swallowed by the
richtextbox which has keyboardfocus.
How about overwriting that KeyBinding with a custom command that does what you want instead of trying to somehow disable it?
<RichTextBox.InputBindings>
<KeyBinding Command="local:YourCommands.Cmd1" Gesture="CTRL+1" />
<RichTextBox.InputBindings>
Taken from this question.
Using the code from this answer
How can I programmatically generate keypress events in C#?
to refire all events on PreviewKeyDown other than those you want handled by the richtextbox seems to work for me. (I only need Ctrl-C for copy). Of course you could make it so it only refires Ctrl-1 if that's what you need.
private void logKeyHandler(object sender, KeyEventArgs e)
{
if (!(Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.C))
{
e.Handled = true;
var routedEvent = Keyboard.KeyDownEvent;
this.RaiseEvent(
new KeyEventArgs(
Keyboard.PrimaryDevice,
PresentationSource.FromDependencyObject(this),
0,
e.Key) { RoutedEvent = routedEvent }
);
}
}
What about trying with the gesture instead...
<RichTextBox.InputBindings>
<KeyBinding Command="BlockTheCommand" Gesture="CTRL+1" />
</RichTextBox.InputBindings>