Shortcut hotkey for WPF - c#

I used UserControl for my application and i need to put shortcut key for my application i placed this code but not working.Anyone suggestion plz
My XAML Code
<Button Name="ucBtnUpload" ToolTip="Upload F2" Cursor="Hand" Click="ucBtnUpload_Click" KeyUp="ucBtnUpload_KeyUp_1" >
My Code Behind
private void ucBtnUpload_KeyUp_1(object sender, KeyEventArgs e)
{
if (e.Key == Key.F2)
{
Test opj = new Test();
opj.ShowDialog();
}
}

You need to try something similar to this
private void AddHotKeys()
{
try
{
RoutedCommand firstSettings = new RoutedCommand();
firstSettings.InputGestures.Add(new KeyGesture(Key.A, ModifierKeys.Alt));
CommandBindings.Add(new CommandBinding(firstSettings , My_first_event_handler));
RoutedCommand secondSettings = new RoutedCommand();
secondSettings.InputGestures.Add(new KeyGesture(Key.B, ModifierKeys.Alt));
CommandBindings.Add(new CommandBinding(secondSettings , My_second_event_handler));
}
catch (Exception err)
{
//handle exception error
}
}
Events
private void My_first_event_handler(object sender, ExecutedRoutedEventArgs e)
{
//handler code goes here.
MessageBox.Show("Alt+A key pressed");
}
private void My_second_event_handler(object sender, RoutedEventArgs e)
{
//handler code goes here.
MessageBox.Show("Alt+B key pressed");
}
If you are following MVVM you could try this reference
<UserControl.InputBindings>
<KeyBinding Modifiers="Control"
Key="E"
Command="{input:CommandBinding EditCommand}"/>
See the reference
msdn adding key bindings

You should be able to do this in your xaml
<Window.InputBindings>
<KeyBinding Command="{Binding MyCommand}" Key="F2"/>
</Window.InputBindings>
<Button Command="{Binding MyCommand}"/>
MyCommand is an ICommand implemented in your windows' / view's viewmodel.
So both the button and the F2 inputbinding will execute the same command.

Related

Keyboard accelerator firing when writing to Textbox

Click event of Button is fired when pressing D while writing to Textbox.
Is there an elegant way how to suppress Keyboard Accelerator while Textbox is focused?
XAML:
<StackPanel Orientation="Vertical">
<TextBox></TextBox>
<Button Click="Button_Click" Content="Button with "D" as keyboard accelerator" Margin="0,10">
<Button.KeyboardAccelerators>
<KeyboardAccelerator Key="D"></KeyboardAccelerator>
</Button.KeyboardAccelerators>
</Button>
<TextBlock x:Name="ButtonClickCounter"></TextBlock>
</StackPanel>
C#:
int buttonClickCounter;
private void Button_Click(object sender, RoutedEventArgs e)
{
ButtonClickCounter.Text = $"Button clicked {++buttonClickCounter} times";
}
EDIT:
Why Accelerator with Modifier (Alt+D or Ctrl+D) is not solution?
I am creating video player and I found that one-key shortcuts are neat solution for fast operations with video player (same as in VLC).
Best Solution so far:
Creating custom KeyboardAccelerator, that checks if focus is set to text box. Only edit in code that need to be done is changing KeyboardAccelerator to AcceleratorWithHandledActionIfTextboxIsFocused.
public class AcceleratorWithHandleDActionIfTextboxIsFocused:KeyboardAccelerator
{
public AcceleratorWithHandleActionIfTextboxIsFocused()
{
Invoked += AcceleratorWithHandleActionIfTextboxIsFocused_Invoked;
}
private void AcceleratorWithHandleActionIfTextboxIsFocused_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
var focusedElement = FocusManager.GetFocusedElement();
if (focusedElement.GetType() == typeof(TextBox))
args.Handled = true;
}
}
part of XAML:
<Button.KeyboardAccelerators>
<custom:AcceleratorWithHandleDActionIfTextboxIsFocused Key="D"></KeyboardAccelerator>
</Button.KeyboardAccelerators>
I agree with #Thomas Weller in his comments as for not using a single letter as a keyboard accelerator...
But everybody has their own requirements, anyway, you could try to e.handle = true your event when textbox is focused.
Something like this:
public void Button_Click(object sender, ExecutedRoutedEventArgs e)
{
if (textBox.isFocused)
{
e.handled = true;
}
}

WPF: Figuring out whether a MouseBinding is a single click or double click

Im using Mousebindings in my view to listen to user clicks like this:
<Path.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding DoubleLeftClickProj}" />
<MouseBinding Gesture="LeftClick" Command="{Binding SingleLeftClick}"/>
</Path.InputBindings>
I only need one of the mouse gestures at a time. So if I double click on my application I want to ignore the single left click mousebinding. Possibly like waiting 1-2sec after the initial mouseclick then decided which should be called. Is there a simple way of doing this?
I got it working the following way (I used a Button to test it, you'll have to adapt it).
Use Event Handlers
<Button MouseDoubleClick="Button_MouseDoubleClick" Click="Button_Click"></Button>
store the DataContext in a static variable
private static object context;
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
context = DataContext;
}
Adapt this code (I mainly got it from https://stackoverflow.com/a/971676/4792869)
private static DispatcherTimer myClickWaitTimer =
new DispatcherTimer(
new TimeSpan(0, 0, 0, 1),
DispatcherPriority.Background,
mouseWaitTimer_Tick,
Dispatcher.CurrentDispatcher);
private void Button_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
// Stop the timer from ticking.
myClickWaitTimer.Stop();
((ICommand)DataContext).Execute("DoubleLeftClickProj");
e.Handled = true;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
myClickWaitTimer.Start();
}
private static void mouseWaitTimer_Tick(object sender, EventArgs e)
{
myClickWaitTimer.Stop();
// Handle Single Click Actions
((ICommand)context).Execute("SingleLeftClick");
}

WPF disabling the window close button via MVVM

I am trying to disable the close button on a window via MVVM
I realise that you can do this in the view (window) CS code by stating
public Window()
{
InitializeComponent();
this.Closing += new System.ComponentModel.CancelEventHandler(Window_Closing);
}
void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
}
However I would like to keep it consistent and try to do this is the MVVM.
Thanks
It's a strange demand. If you have a closing button,why you disable it's func. But you can realize it with mvvm like this:
add two ref:
- Microsoft.Expression.Interactions.dll
- System.Windows.Interactivity.dll
add two xmlns:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
create trigger to window:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:control="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
Title="MainWindow" Height="350" Width="525">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<ei:CallMethodAction TargetObject="{Binding}" MethodName="WindowsClosing"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid >
</Grid>
</Window>
edit viewmodel,and creat closing func:
public void WindowsClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
}
Change your Closing method with a variable from ViewModel.
void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = (this.DataContext as MyViewModel).ProcessWorking;
}
In your ViewModel (MyViewModel) add a property ProcessWorking :
public Boolean ProcessWorking
{
get { return this.processWorking; }
}
and in your method of background thread, just modify processWorking
private Boolean processWorking;
private void MyBackgroundThread()
{
this.processWorking = true;
// do your process
this.processWorking = false;
}
You can add a RaisePropertyChange() when you modify this.processWorking if you want to show somewhere of your UI the state of the background process.
you can use the ResizeMode of Window or you can use it by using Window API use of Window API mentioend Here

How to detect DoubleClick in WPF ToggleButton

In my WPF application I have Toggle Button, I want to detect when user double click on it (in both cases if it checked or unchecked).
How can I do that?
Thanks in advance
You can use the OnPreviewMouseDoubleClick event
xaml:
<ToggleButton Height="75" Width="100" PreviewMouseDoubleClick="Control_OnPreviewMouseDoubleClick"/>
code-behind:
private void Control_OnPreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
var toggleButtton = sender as ToggleButton;
if (toggleButtton != null)
{
if (toggleButtton.IsChecked.HasValue)
{
if (toggleButtton.IsChecked.Value)
{
// Checked
}
else
{
// Unchecked
// this will re-check the button if double-click unchecks it
//
toggleButtton.IsChecked = true;
toggleButtton.Focus();
}
}
}
}
Use PreviewMouseDoubleClick event (msdn):
XAML:
<ToggleButton x:Name="tButton" Height="30" Content="MyButton"
PreviewMouseDoubleClick="tButton_PreviewMouseDoubleClick"
/>
Code-behind:
private void tButton_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
tButton.IsChecked = !tButton.IsChecked.Value;
e.Handled = true;
//...
}
This event is pretty easy with togglebuttons
Xaml you write the following to get an EventHandler:
<ToggleButton Name="button1" MouseDoubleClick="button1_DoubleClick" />
In c# you write the following to get an EventHandler:
button1.MouseDoubleClick += new MouseButtonEventHandler(button1_DoubleClick);
And in both cases you need:
void button1_DoubleClick(object sender, MouseButtonEventArgs e)
{
}

Open and Close the same window on the same button click

On my MenuItem at the moment I open up a Window. Then if the person chooses to click on that MenuItem again, I need the Window that was open to close.
Then obviously, if they click it the third time it will open and so fourth.
XAML
<MenuItem x:Name="btnHelp" Click="btnHelp_Click" Foreground="#FF7E8385" FontFamily="Calibri" FontSize="18" Margin="110,10,0,0" Height="30" Width="70" Style="{x:Null}" BorderBrush="Transparent" Background="Transparent" Cursor="Hand"/>
Code behind
private void btnHelp_Click(object sender, RoutedEventArgs e)
{
xamlHelp help = new xamlHelp();
help.Show();
}
You'll need to have the variable be an instance field, rather than a local variable, so it can be accessed between calls. At that point just close it if it exists, and recreate/show it if it doesn't:
private xamlHelp help = null;
private void btnHelp_Click(object sender, RoutedEventArgs e)
{
if (help != null)
{
help.Close();
help = null;
}
else
{
help = new xamlHelp();
help.Show();
}
}
You can keep track of whether the help is currently showing and show/hide based on that,
private xamlHelp help = new xamlHelp();
private bool showingHelp = false;
private void btnHelp_Click(object sender, RoutedEventArgs e)
{
if (showingHelp)
{
help.Hide();
}
else
{
help.Show();
}
}

Categories