How to use ApplicationCommands with Fluent.Ribbon? - wpf

I have a fluent.ribbon with the traditional buttons cut, copy and paste and try to hook up to the corresponding ApplicationCommands. However, the buttons are disabled and doesn't work as e.g. when having them in a menu. How can I use ApplicationCommands with fluent.ribbon?
The commands work with e.g. menuitems.
<Fluent:RibbonGroupBox Header="Clipboard">
<Fluent:Button Header="Paste" Command="ApplicationCommands.Paste" Icon="./Assets/Paste_96x.png" LargeIcon="./Assets/Paste_96x.png"/>
<Fluent:Button Header="Copy" Command="ApplicationCommands.Copy" SizeDefinition="Middle" Icon="./Assets/Copy_96x.png" LargeIcon="./Assets/Copy_32x.png"/>
<Fluent:Button Header="Cut" Command="ApplicationCommands.Cut" SizeDefinition="Middle" Icon="./Assets/Cut_96x.png" LargeIcon="./Assets/Cut_96x.png"/>
</Fluent:RibbonGroupBox>

Using FocusManager did the trick.
<Fluent:RibbonGroupBox Header="Clipboard">
<Fluent:Button Header="Paste" Command="ApplicationCommands.Paste" FocusManager.IsFocusScope="True" Icon="./Assets/Paste_96x.png" LargeIcon="./Assets/Paste_96x.png"/>
<Fluent:Button Header="Copy" Command="ApplicationCommands.Copy" FocusManager.IsFocusScope="True" SizeDefinition="Middle" Icon="./Assets/Copy_96x.png" LargeIcon="./Assets/Copy_32x.png"/>
<Fluent:Button Header="Cut" Command="ApplicationCommands.Cut" FocusManager.IsFocusScope="True" SizeDefinition="Middle" Icon="./Assets/Cut_96x.png" LargeIcon="./Assets/Cut_96x.png"/>
</Fluent:RibbonGroupBox>

Related

wpf extend contextmenu of textbox

I am searching for a way to extend the contextmenu of a textbox. I know there are dozens of solutions out there that recreate the contextmenu as a whole, but how on earth can I simply add one custom entry to a existing context menu?
Thanks
Klaus
<TextBox>
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Command="ApplicationCommands.Cut" />
<MenuItem Command="ApplicationCommands.Copy" />
<MenuItem Command="ApplicationCommands.Paste" />
<MenuItem Command="ApplicationCommands.SelectAll" />
//Your own item here
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
Please not that all command are automatically operation and will work as expected

How can I take different MenuItem controls and use them in one ContextMenu?

For example, I have a simple control below in xaml:
<ContextMenu>
<MenuItem Header = "Open in new tab"/>
<MenuItem Header = "Open in new window"/>
<MenuItem Header = "Open in incognito window"/>
<Separator Padding="0"/>
<MenuItem Header = "Edit..."/>
<Separator Padding="0"/>
<MenuItem Header = "Cut"/>
<MenuItem Header = "Copy"/>
<MenuItem Header = "Paste"/>
<Separator Padding="0"/>
<MenuItem Header = "Delete"/>
</ContextMenu>
Which produces:
I want the Cut/Copy/Paste MenuItem elements to sit in their own control. However, Wpf restricts me from just declaring 3 MenuItems in a control without a parent element. So I tried putting the MenuItems in a Menu, Grid, ItemsControl, and other controls with no luck. The formatting was weird. All i want to do is abstract the Cut/Copy/Paste into a seperate control, and have the end product look identical to the xaml above. Here were my failed attempts:
MyContextMenu.xaml:
<ContextMenu>
<MenuItem Header = "Open in new tab"/>
<MenuItem Header = "Open in new window"/>
<MenuItem Header = "Open in incognito window"/>
<Separator Padding="0"/>
<MenuItem Header = "Edit..."/>
<Separator Padding="0"/>
<ref:MyCutCopyPaste/>
<Separator Padding="0"/>
<MenuItem Header = "Delete"/>
</ContextMenu>
MyCutCopyPaste.xaml:
<Grid>
<MenuItem Header = "Cut"/>
<MenuItem Header = "Copy"/>
<MenuItem Header = "Paste"/>
<Grid>
I can probably take my solution and play around with formatting, but there has to be an easy solution that I'm oblivious too. I know I can also declare each Menu Item (Cut, Copy, and Paste) into it's own xaml file. But I'd like to keep all three in one file, if possible.
You can define those MenuItems as resources and use it in the contextmenu. Refer the below code.
<StackPanel>
<StackPanel.Resources>
<MenuItem x:Key="Cut" Header="Cut" x:Shared="false"/>
<MenuItem x:Key="Copy" Header="Copy" x:Shared="false"/>
<MenuItem x:Key="Paste" Header="Paste" x:Shared="false"/>
</StackPanel.Resources>
<Button Content="Button 1">
<Button.ContextMenu>
<ContextMenu>
<StaticResourceExtension ResourceKey="Cut"/>
<StaticResourceExtension ResourceKey="Copy"/>
<StaticResourceExtension ResourceKey="Paste"/>
<MenuItem Header="Open in new tab"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
<Button Content="Button 2">
<Button.ContextMenu>
<ContextMenu>
<StaticResourceExtension ResourceKey="Cut"/>
<StaticResourceExtension ResourceKey="Copy"/>
<StaticResourceExtension ResourceKey="Paste"/>
<MenuItem Header="Open in new window"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
</StackPanel>

WPF UserControl - Binding parent window as command parameter to ContextMenu MenuItem

I have a UserControl with Button inside which opens a ContextMenu when left clicked. I'm trying to pass UserControl's parent Window as a parameter to ContextMenu item's command to close that window, but with no avail. I've tried everything with RelativeSource and PlacementTarget, but parameter is always null. I'm aware that ContextMenu is not part of parent window's VisualTree. I'm currently stuck with this approach, but it is not working.
<Grid x:Name="LayoutRoot">
<Button
HorizontalAlignment="Left"
Margin="0"
Style="{DynamicResource ButtonStyle1}"
VerticalAlignment="Top"
Width="120"
Height="25"
Content="Dashboard Menu"
TextElement.FontWeight="Bold"
Foreground="AliceBlue"
>
<!--Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={ x:Type Window}}}"-->
<Button.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}" >
<MenuItem Header="Open Log Viewer" Command="{StaticResource openLogViewer}" />
<Separator />
<MenuItem Header="Exit" Command="{StaticResource exit}" CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType=Window}}"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
</Grid>
Command is a Referenced command defined in UserControl.Resources:
<my:CommandReference x:Key="exit" Command="{Binding Exit}" />
and it's Execute part is triggered but parameter is always null. So, my question is, what is the right way to bind parent window as CommandParameter of MenuItem. Any help is appreciated, because this thing is bothering me for almost two days.
Right way here is to not pass parent Window to the VM as CommandParameter. If this is MVVM you should be using a Messenger(MVVM Light) / EventAggregator(Prism) approach to send a Message to the Window's code-behind when the command is triggered to Close it.
Referencing Window in the VM is just plain wrong.
Just for reference, what your trying to do "can be done"
something like:
<Grid x:Name="LayoutRoot">
<Button HorizontalAlignment="Left"
Margin="0"
Style="{DynamicResource ButtonStyle1}"
VerticalAlignment="Top"
Width="120"
Height="25"
Content="Dashboard Menu"
TextElement.FontWeight="Bold"
Foreground="AliceBlue"
Tag="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}}">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Open Log Viewer" Command="{StaticResource openLogViewer}" />
<Separator />
<MenuItem Command="{StaticResource exit}"
CommandParameter="{Binding PlacementTarget.Tag,
RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"
Header="Exit" />
...
Update:
Download Link
When executing the "Exit" command from the ContextMenu you should see Sender Object: MvvmLight16.MainWindow in your Output Window. This output is sent from the VM.

XAML and Binding Submenu items in a ContextMenu?

I have a ContextMenu defined on a Datagrid but want to bind submenu items to a collection on my viewmodel. Can anybody suggest how this should be done?
The following is a simple example of what I'm trying to achieve, BUT I want "Test1", "Test2" to come from a collection on my viewmodel, not hardcoded. I know how to bind my collection to the whole ContextMenu, but not how to bind it to just the one submenu...
<ContextMenu>
<MenuItem Header="Add to">
<MenuItem Header="Test1" />
<MenuItem Header="Test2" />
</MenuItem>
<MenuItem Header="Remove from All" />
</ContextMenu>
I'm using 3.5 SP1 and the WPF Toolkit.
Guess I should have experimented more. Turns out this was relatively simple:
<my:DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Add to" ItemsSource="{Binding MyItems}">
<MenuItem.ItemTemplate>
<DataTemplate>
<MenuItem CommandTarget="{Binding}" Click="AddClick">
<MenuItem.Header>
<TextBlock>
<TextBlock.Text><Binding StringFormat="Add to {0}" /></TextBlock.Text>
</TextBlock>
</MenuItem.Header>
</MenuItem>
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
<MenuItem Header="Remove from All" />
</ContextMenu>
</my:DataGrid.ContextMenu>
There is a bug when using MenuItem.ItemTemplate. The color when do mouse over on the sub menu make user misunderstand that they can click to select the menu but it doesn't work for all area even if it's highlighted. See the picture
Then I used this code instead and it worked fine for me.
<ContextMenu>
<MenuItem Header="Add to" ItemsSource="{Binding MyItems}"
DisplayMemberPath="{Binding ItemName}">
<MenuItem.ItemContainerStyle>
<Style>
<EventSetter Event="MenuItem.Click" Handler="Menu_Click"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
<MenuItem Header="Remove from All" />
</ContextMenu>

wpf how to update Window

I have made my application multilingual. It changes it's language when you click the corresponding menuitem. This works fine but my problem comes when my parent window doesn't change it's language (menu is in parent window). All child windows change their language. Is there any way to force window to load again? I have done my application with resx-files and also checked that Thread.CurrentThread.CurrentCulture and Thread.CurrentThread.CurrentUICulture are changed when menuitem is clicked.
Edit:
I have made my own class to do the multilingual part and it is an adaptation from this article's approach: WPF Runtime Localization, it works. Here is a part of my XAML code to show the databindings:
<Window x:Class="Multilingual.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:properties="clr-namespace:Multilingual.Properties"
Height="350" Width="300" Name="mainWindow" ResizeMode="CanMinimize" SizeToContent="Manual" Closing="mainWindow_Closing" KeyDown="mainWindow_KeyDown">
and
<Menu Height="22" Name="menu" Width="{Binding ElementName=mainWindow, Path=Width}" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Snow" BorderThickness="2">
<Menu.BitmapEffect>
<DropShadowBitmapEffect />
</Menu.BitmapEffect>
<MenuItem Header="{x:Static properties:Resources.Menu}">
<MenuItem Header="{x:Static properties:Resources.Language}" >
<MenuItem Header="{x:Static properties:Resources.Deutsch}" Name="itemDeutsch" Click="menuItem_Click" />
<MenuItem Header="{x:Static properties:Resources.English}" Name="itemEnglish" Click="menuItem_Click" />
</MenuItem>
<MenuItem Header="{x:Static properties:Resources.Exit}" Click="itemExit_Click"/>
</MenuItem>
</Menu>
So I think it would be enough if I would be able to update the window somehow.
WPF: How to change the CurrentUICulture at runtime
I found a solution. I changed my databindings to look like this:
<MenuItem Header="{Binding Path=Menu, Source={StaticResource Resources}}">
Where "Menu" corresponds the MenuItem's name in resx-file.

Resources