This question already has answers here:
Keyboard shortcuts in WPF
(11 answers)
Closed 9 years ago.
How Can I Add Short Cut Key To button in wpf?
I have three window with New Button and i want to add Ctrl+N or etc short cut to all of them.
you can do it as following method too. in form write method indicating short cut keys.
private void shortcutKey_Click(object sender, System.Windows.Input.KeyEventArgs e)
{
if ((e.Key == Key.N) && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
ProjMnuBtn_AddProj_Click(null, null);
}
then in xaml file you need to set it as follows:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="1280" Height="920" KeyUp="shortcutKey_Click">
</Window>
Here is a great tutorial for this : https://web.archive.org/web/20150430045153/http://tech.pro:80/tutorial/839/wpf-tutorial-command-bindings-and-custom-commands
Sample (taken from link above)
<Window x:Class="CustomCommandTest.CommandWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Custom Command Test" Height="300" Width="300">
<Window.CommandBindings>
<CommandBinding Command="Help"
CanExecute="HelpCanExecute"
Executed="HelpExecuted" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Command="Help" Key="H" Modifiers="Ctrl"/>
<MouseBinding Command="Help" MouseAction="LeftDoubleClick" />
</Window.InputBindings>
<StackPanel>
<Button Command="Help" Content="Help Command Button" />
<Button Content="My Command" x:Name="MyCommandButton" />
</StackPanel>
</Window>
Related
This question already has answers here:
If the user logs on successfully, then I want to show the main window, if not, I want to exit the application
(3 answers)
Closed 4 years ago.
I have a main window that I created and it looks like usual log in screen.
Once the user click on a button I would like the whole window to change.
In all the examples I saw either I have to keep a stackpanel/dock and then only the frame changes.
For example, I have the following Main window xaml:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Frame x:Name="Main" Margin="0,35,0,0"/>
<Button Content="Button" Click="Button_Click" Margin="0,105,326,100"/>
</Grid>
</Window>
and the new page:
<Page x:Class="WpfApp1.Optimizer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Optimizer">
<Grid Background="Black">
<Button Content="Button" HorizontalAlignment="Left" Height="91" Margin="125,87,0,0" VerticalAlignment="Top" Width="129"/>
</Grid>
</Page>
And my command is:
private void Button_Click(object sender, RoutedEventArgs e)
{
Main.Content = new Optimizer();
}
In that case the two views appear on same page instead of switching completely.
Its not the case im looking for. I need the whole window to change and not leave behind a stackpanel.
Any simple example would be appreciated.
First thing to mention here is that pages and frames are rarely used by commercial teams. At least not in my experience.
Unless writing xbap - which is wpf in a browser.
I suggest you consider usercontrols rather than pages and host them in contentcontrols.
You can then have something like:
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Click="Button_Click"/>
</Grid>
</Window>
Click handler:
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Content = new UserControl1();
}
That makes the entire content of mainwindow an instance of UserControl1.
A Window inherits from contentcontrol.
You should also have learning mvvm on your list.
You should learn that. Maybe not right now, but soon.
This question already has an answer here:
CommandConverter cannot convert from System.String in WPF
(1 answer)
Closed 8 years ago.
<Window x:Class="CostelloM_Data_Persistence_v1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ContactMyPeeps(IllegalVersion)" Height="350" Width="525">
<Window.Resources>
<RoutedCommand x:Key="Saveas"/>
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="Saveas" Executed="Save_As"/>
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="S"
Modifiers="Control + Shift"
Command="Saveas"/>
</Window.InputBindings>
<Grid>
<StackPanel Orientation="Vertical">
<Menu>
<MenuItem Header="File">
<MenuItem Command="Save" Header="Save"/>
<MenuItem Command="Saveas" Header="Save as" InputGestureText="Ctrl+Shift+S"/>
<MenuItem Command="Open" Header="Open"/>
</MenuItem>
</Menu>
<ItemsControl>
<ComboBox>
</ComboBox>
</ItemsControl>
</StackPanel>
</Grid>
</Window>
My problem is as follows, the above code will not compile. I have tried saving, cleaning, and rebuilding my visual studio project and still no dice. It says that command converter cannot convert from system.string. Clearly I either misunderstand RoutedCommand and can not use in this way as a custom command. Is there either a way to force RoutedCommand to create a new command, or a different way to use a custom command?
You are defining a command in a resource so you need to tell the binding system that it is in a resource. You need to change several places in the XAML to this
Command="{StaticResource Saveas}"
However, there are several standard commands pre-defined for you in the ApplicationCommands class like Open, Save, and SaveAs. The binding system will automatically try to bind to these but casing is important. This:
Command="SaveAs"
will bind to the appropriate command defined in ApplicationCommands. Then the command defined in the resources becomes unnecessary.
You've got typos on several lines, which is most likely giving you a "CommandConverter cannot convert from System.String" error because it doesn't recognize the command.
Change this:
<CommandBinding Command="Saveas" Executed="Save_As"/>
To this: (uppercase "A")
<CommandBinding Command="SaveAs" Executed="Save_As"/>
I have a WPF Window containing a TabControl, which has Frames in it which display Pages. Like this:
<Window x:Class="MyNamespace.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow">
<DockPanel>
<TabControl x:Name="TabControl">
<TabItem Header="StartScreen" x:Name="StartScreenTab">
<Frame Source="StartScreenPage.xaml"/>
</TabItem>
<TabItem Header="OtherTab" x:Name="OtherTab">
<Frame Source="OtherPage.xaml"/>
</TabItem>
</TabControl>
</DockPanel>
</Window>
In one of the pages, I have a KeyBinding:
<Page x:Class="MyNamespace.View.OtherPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Title="OtherPage">
<Page.InputBindings>
<KeyBinding Key="U" Modifiers="Control" Command="{Binding MyCommand}"/>
</Page.InputBindings>
<!-- Content ... -->
</Page>
MyCommand is a property of OtherPage.DataContext, it's only available from the page, not available from outside.
My problem is that the KeyBinding only works after I click on a control inside the Page. I want that KeyBinding to work whenever OtherPage is visible, equivalently when OtherTab is the active tab. How can I achieve this?
The only way that you can achieve that is to move your KeyBinding and the ICommand implementation to the MainWindow.xaml file:
<Window.InputBindings>
<KeyBinding Key="U" Modifiers="Control" Command="{Binding MyCommand}"/>
</Window.InputBindings>
If you can't move the actual implementation of the ICommand, then you must at least make it accessible from there.
I did something similar to what Sheridan recommended in his answer.
In MainWindow.xaml I declare a RoutedUICommand:
<Window x:Class="MyNamespace.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow">
<Window.Resources>
<ResourceDictionary>
<RoutedUICommand x:Key="OtherPageCommand"/>
</ResourceDictionary>
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="{StaticResource OtherPageCommand}"
Executed="OtherPageCommandExecuted"/>
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="U" Modifiers="Control" Command="{StaticResource OtherPageCommand}"/>
</Window.InputBindings>
<DockPanel>
<TabControl x:Name="TabControl">
<TabItem Header="StartScreen" x:Name="StartScreenTab">
<Frame Source="StartScreenPage.xaml"/>
</TabItem>
<TabItem Header="OtherTab" x:Name="OtherTab">
<Frame Source="OtherPage.xaml"/>
</TabItem>
</TabControl>
</DockPanel>
</Window>
In MainWindow.xaml.cs I have this method:
private void OtherPageCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
var page = ((Frame)((TabItem) TabControl.SelectedItem).Content).Content as OtherPage;
if (page != null)
{
var viewModel = page.DataContext as MyViewModel;
if (viewModel != null)
{
var openWindow = viewModel.MyCommand;
var parameter = null; // put your command parameter here
if (openWindow.CanExecute(parameter))
openWindow.Execute(parameter);
}
}
}
This way I propagate the keybinding to the page but the actual command remains in the viewmodel of the page.
I have a window:
<Window x:Class="SomeNamespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="350" Width="525">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy"
CanExecute="CommandCanExecute" Executed="CommandExecuted"/>
</Window.CommandBindings>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Command="ApplicationCommands.Copy"/>
</MenuItem>
</Menu>
</DockPanel>
</Window>
With some code behind:
void CommandCanExecute(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = true;
}
void CommandExecuted(object sender, EventArgs e) {
MessageBox.Show("Done!");
}
And everything works the way I expect. I can use the MenuItem or the Ctrl+C input binding to run my command.
But now my class has gotten too big, and I decide to refactor. So I moved my code behind to a user control. Here's my new Window:
<Window x:Class="SomeNamespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:SomeNamespace"
Height="350" Width="525">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Command="ApplicationCommands.Copy"/>
</MenuItem>
</Menu>
<my:UserControl1/>
</DockPanel>
</Window>
And my UserControl:
<UserControl x:Class="ImageDecompileSandbox.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy"
CanExecute="CommandCanExecute" Executed="CommandExecuted"/>
</UserControl.CommandBindings>
</UserControl>
Basically, everything is the same, except the CommandBinding was moved from the window to UserControl and the two command methods were pushed down to the user control.
Question: Why does the above not work? Why is my User Control's command not picked up by the window? How do I get the MenuItem / KeyBindings from the window to work with the command execution in the User Control?
Thanks to dkozl, I was able to find a way to make this work.
The trick was indeed adding the CommandBinding back to the Window. Instead of declaring them all in the Window, which I can't do as the window doesn't know about the methods being used for Executed and CanExecute, I just added all the bindings from the control to the window:
CommandBindings.AddRange(_userControl1.CommandBindings);
I find this one-line hack to be exactly what I need, as it lets me keep the command controls and keybindings in the window while moving the command implementation to the control.
Thanks for the help dkozl!
I bind my textboxes to ViewModel class. But, button command (it's a RelayCommand, extended from ICommand) I bind to UsersView.xaml.cs. In UsersView.xaml.cs constructor I have this:
DataContext = UserVM;
btnAdd.DataContext = this;
This is how I bind button - it works.
<Button Command="{Binding Add}" Content="Add user" />
Now, I want to add KeyGesture for that button but I can't set DataContext for InputBindings and compiler can't find this Add command in UsersVM class.
<UsersView.InputBindings>
<KeyBinding Key="F10" Command="{Binding Add}" />
</UsersView.InputBindings>
I had this on a Window and this is the code I used...
<Window
x:Class="MVVMExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myViewModels="clr-namespace:MVVMExample"
Title="MainWindow"
x:Name="MyMainWindow"
Height="350"
Width="525">
Notice that I set the x.Name of the Window. Then in my KeyBinding, I did this...
<Window.InputBindings>
<KeyBinding
Key="F10"
Command="{Binding ElementName=MyMainWindow, Path=DataContext.AddPersonCommand}" />
</Window.InputBindings>
The AddPersonCommand is my ICommand from my ViewModel.