I have an WPF desktop application and many text boxes that automatically have the default context menu with Copy\Cut\Paste commands.
Is there any way to change style of this menu, for example add icons or change Foreground color?
https://ibb.co/y5LRZnY
You could create a TextBox style with a custom ContextMenu:
<Style TargetType="TextBox">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu Foreground="Red">
<MenuItem Icon="..." Command="Cut"/>
<MenuItem Icon="..." Command="Copy"/>
<MenuItem Icon="..." Command="Paste"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
And here is how you would set the Icon property of a MenuItem to an image:
<MenuItem Command="Paste">
<MenuItem.Icon>
<Image Source="pic.png" />
</MenuItem.Icon>
</MenuItem>
Related
I am desinging a wpf application. I code a grid(which has 35 textblocks)-wide context menu. when I click mouse's right button I need to learn on which textblock I clicked. But click event gives centext menu as a sender. How can I reach on which textblock the user click right mouse button?
My XAML code---------------------------------------------------------------:
<Grid>
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Hafta İçi" x:Name="btnWeekDay" Click="btnWeekDay_Click" />
<MenuItem Header="Cuma" x:Name="btnFriday" Click="btnFriday_Click"/>
<MenuItem Header="Cumartesi" x:Name="btnSaturday" Click="btnSaturday_Click"/>
<MenuItem Header="Pazar" x:Name="btnSunday" Click="btnSunday_Click"/>
<MenuItem Header="İdari İzin" x:Name="btnAdminLeave" Click="btnAdminLeave_Click"/>
<MenuItem Header="Bayram/Tatil" x:Name="btnHoliday" Click="btnHoliday_Click" a/>
</ContextMenu>
</Grid.ContextMenu>
My C# code-------------:
private void btnWeekDay_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(sender + e.Source.ToString());
}
I found the answer.
1. I moved contextmenu from grid to the textblocks.
2. I fired contextmenuopening event and catch the texblock on which I click rght mouse button.
Here is the xaml code.
<Page.Resources>
<Style x:Key="txtBlockStyle" TargetType="{x:Type TextBlock}">
<Setter Property="TextBlock.Background" Value="AliceBlue"/>
</Style>
<Style x:Key="borderStyle" TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="DarkGreen"/>
</Style>
<ContextMenu x:Key="txtBlockContextMenu">
<MenuItem Header="Hafta İçi" x:Name="btnWeekDay" Click="btnWeekDay_Click" />
<MenuItem Header="Cuma" x:Name="btnFriday" Click="btnFriday_Click"/>
<MenuItem Header="Cumartesi" x:Name="btnSaturday" Click="btnSaturday_Click"/>
<MenuItem Header="Pazar" x:Name="btnSunday" Click="btnSunday_Click"/>
<MenuItem Header="İdari İzin" x:Name="btnAdminLeave" Click="btnAdminLeave_Click"/>
<MenuItem Header="Bayram/Tatil" x:Name="btnHoliday" Click="btnHoliday_Click" />
</ContextMenu>
</Page.Resources>
.....
<Border Style="{StaticResource borderStyle}" Grid.Column="0" Grid.Row="1" >
<TextBlock x:Name="txtDate1" ContextMenuOpening="CustomContextMenuOpening" ContextMenu="{StaticResource ResourceKey=txtBlockContextMenu}"></TextBlock>
</Border>
Here is code behind.
TextBlock targetTextBlock;
private void CustomContextMenuOpening(object sender, ContextMenuEventArgs e)
{
targetTextBlock = (TextBlock)sender;
}
I am searching for a solution for the ContextMenu's commands defined under ListViewItem style. Binding was successful when I defined and bind the commands inside ContextMenu within ListView.
I used viewModel class file to define the commands ex: ExecuteClone, CanExecuteClone which i am trying to bind it with ContextMenu menu items using Command Binding.
<ListView.ContextMenu>
<ContextMenu >
<MenuItem Header="New" Command="{Binding AddCommand}" />
</ContextMenu>
</ListView.ContextMenu>
But when i change the ContextMenu from ListView to ListViewItem, it doesn't hit the ViewModel command.
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="New" Command="{Binding AddCommand}"/>
<MenuItem Header="Clone" Command="{Binding CloneCommand}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
It needs to hit the ViewModel AddCommand, CloneCommand which are DelegateCommand actions defined under ViewModel class.
I found the answer with some trials, anyways thanks for the help.
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType=ListView}, Path=DataContext}"/>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="New" Command="{Binding AddCommand}"/>
<MenuItem Header="Clone" Command="{Binding CloneCommand}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
The ListViewItems have a different DataContext than the ListView. Every ListViewItem has its DataContext set to one of the items in your ItemsSource collection, so this is why the binding doesn't work. If you want to bind the commands to the ListView's DataContext, you can do it like that:
Command="{Binding DataContext.AddCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=ListView}}"
I am facing an issue with MenuItem that whenever I specify an access key, the header alignment is getting disrupted. Below is a sample image wherein I have specified "_New" for New menu item and bound it to New command. You can observe tha the Text "New" is align at bottom and shortcut key is aligned at top. Also for other menu items I have not specified any access key, so they have no issue.
Here is the XAML
<StackPanel DockPanel.Dock="Top">
<Menu Padding="0,5">
<MenuItem x:Name="MnuTask" Header="Task">
<MenuItem x:Name="MnuNew" Header="_New" Command="New"/>
<MenuItem x:Name="MnuSave" Header="Save" Command="Save"/>
<MenuItem x:Name="MnuDelete" Header="Delete" Command="Delete"/>
<Separator/>
<MenuItem x:Name="MnuRefresh" Header="Reload Data" Command="{x:Static Local:MainWindow.RefreshDataCommand}" />
<MenuItem x:Name="MnuHistory" Header="View Range History" Command="{x:Static Local:MainWindow.RangeHistoryCommand}" />
<Separator/>
<MenuItem x:Name="MnuExit" Header="Exit" Command="Close"/>
</MenuItem>
<MenuItem x:Name="MnuView" Header="View">
<MenuItem x:Name="MnuFind" Header="Find Formula"/>
</MenuItem>
</Menu>
</StackPanel>
Could any body let me know what's going on?
Found it. I had the below TextBlock Style present in Resources section of my window. Commenting those lines resolved the issue. (But now I need to apply TextBlock style explicitly using keys :( )
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="3,6,3,0"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
</Style>
I have a ListBox and within it multiple ListBoxItem objects. When the user right-clicks on a ListBoxItem a ContextMenu should appear with some MenuItem objects. The problem that I have is that when I put a Click event on the MenuItem objects I get a XamlParseException stating the following:
A first chance exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll
Additional information: 'Set connectionId threw an exception.' Line number '31' and line >position '34'.
I have to admit that I don't fully understand styles and resources and the other aspects of WPF. When I was designing this I just copied my code from the Internet. The code is as follows:
<ListBox Grid.Column="1" Grid.Row="1" MouseDoubleClick="MainListBox_MouseDoubleClick" Name="mainListBox" SelectionChanged="MainListBox_SelectionChanged">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Click="OpenMenuItem_Click" Header="Open"/>
<Separator/>
<MenuItem Header="Cut"/>
<MenuItem Header="Copy"/>
<Separator/>
<MenuItem Header="Delete"/>
<MenuItem Header="Rename"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
It works when I remove the Click event but of course the ContextMenu becomes useless.
Assign ContextMenu for ListBoxItem as given below.
<ListBox Grid.Column="1" Grid.Row="1" MouseDoubleClick="MainListBox_MouseDoubleClick" Name="mainListBox" SelectionChanged="MainListBox_SelectionChanged">
<ListBox.Resources>
<ContextMenu x:Key="CMenu">
<MenuItem Click="OpenMenuItem_Click" Header="Open"/>
<Separator/>
<MenuItem Header="Cut"/>
<MenuItem Header="Copy"/>
<Separator/>
<MenuItem Header="Delete"/>
<MenuItem Header="Rename"/>
</ContextMenu>
</ListBox.Resources>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu" Value="{StaticResource CMenu}"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBoxItem Content="Test1"/>
</ListBox>
I wish to have two context menu in grid view in my WPf based desktop application .
Currently i am able to display one context menu, but I want to show context menu 1 on one condition and context menu 2 on another condition . How to do that?
I am usign following XAML code to show grid and context menu
<dg:UCGrid x:Name="grdLetVariables" Grid.Row="2" GridTypeSource="LetGrid"
DataContext="{Binding}" >
<dg:UCGrid.Resources>
<x:Array Type="{x:Type sys:Object}" x:Key="GridExtensions">
<MenuItem Header="Delete" Click="ContextMenuDelete">
<MenuItem.Icon>
<Image Height="10" Source="../images/Delete.png"/>
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="Move Up" Click="MoveUpLetGrdRow">
<MenuItem.Icon>
<Image Height="14" Source="../images/UpMove.png"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Move Down" Click="MoveDownLetGrdRow">
<MenuItem.Icon>
<Image Height="14" Source="../images/DownMove.png"/>
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="Cancel" Click="CancelLetGrdRowEdit"/>
</x:Array>
</dg:UCGrid.Resources>
<dg:UCGrid.ContextMenu>
<ContextMenu>
<ContextMenu.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{StaticResource GridExtensions}" />
</CompositeCollection>
</ContextMenu.ItemsSource>
</ContextMenu>
</dg:UCGrid.ContextMenu>
</dg:UCGrid>
</Grid>
Triggers on DataGrid can help you here. Code below is just for illustration ...
<UserContorl.Resources>
<ContextMenu x:Key="Condition1ContextMenu" ../>
<ContextMenu x:Key="Condition2ContextMenu" ../>
</UserControl.Resources>
...
<Style TargetType="{x:Type dg:UCGrid}">
<Style.Triggers>
<DataTrigger Binding="{Binding Condition1}" Value="Value1">
<Setter Property="ContextMenu" Value="{StaticResource Condition1ContextMenu}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Condition2}" Value="Value2">
<Setter Property="ContextMenu" Value="{StaticResource Condition2ContextMenu}"/>
</DataTrigger>
</Style.Triggers>
</Style>
Ofcourse condition1 and condition2 must be exclusive of each other. If both of them are applicable on the data grid then due to order Condition2ContextMenu will take the precedence.
Let me know if this helps...