WPF Menu Item check mark is blacked in Windows 10 - c#

I created a small menu bar with some checked menu items. It is blacked out in Windows 10 but displayed fine in Windows 7
XAML
<Window x:Class="CheckMenuTickinWin10.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:CheckMenuTickinWin10"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<ToolBar>
<Menu>
<MenuItem Header="menu">
<MenuItem Header="Sub" IsCheckable="True" IsChecked="True"/>
<MenuItem Header="Sub" IsCheckable="True" IsChecked="False"/>
<MenuItem Header="Sub" IsCheckable="True" IsChecked="True"/>
</MenuItem>
</Menu>
</ToolBar>
</StackPanel>
</Window>
What should I do in Windows 10 to make the check mark visible?

This background is defined in the default ControlTemplate of the menu item. A template defines the look of a control, if you don't define a template for the control, it will pick up the default template.
The good news is that you are free to edit the ControlTemplate to customize the control as whatever you like. The not so good news is that you have to be comfortable with a bunch of XAML code (hundreds of lines for a single template).
First find the "default" ControlTemplate of the MenuItem in Visual Studio.
In the VS designer, right click the SubMenuItem, and choose "Edit Template" -> "Edit a Copy" from the dropdown menu. This will automatically copy the default template of the SubMenuItem to a style name "MenuItemStyle1" as defined in the window's Resource dictionary.
Remove the black background from the template.
Expand MenuItemStyle1, find the following line that defines the black border.
<Border x:Name="GlyphPanel" BorderBrush="#80DADADA" BorderThickness="1" Background="#FF212121" Height="20" Margin="0,1" Visibility="Hidden" Width="20">
Change the Background color from "#FF212121" to "#FFEEF5FD", and save the change. (#FFEEF5FD is the hightlight color of the border, it is also the color of the light background of the menu, you can find this color in the default template.)
Then apply this new template to all 3 menu items.
<MenuItem Header="menu">
<MenuItem Header="Sub" IsCheckable="True" IsChecked="True" Style="{DynamicResource MenuItemStyle1}" />
<MenuItem Header="Sub" IsCheckable="True" IsChecked="False" Style="{DynamicResource MenuItemStyle1}" />
<MenuItem Header="Sub" IsCheckable="True" IsChecked="True" Style="{DynamicResource MenuItemStyle1}" />
</MenuItem>

Related

CheckBoxes "stealing" bitmaps from each other [duplicate]

I have a MenuItem like below
<MenuItem Header="Edit">
<MenuItem Header="Copy Direct Link" Icon="{StaticResource CopyIcon}" Command="{Binding CopyImageCommand}" />
<MenuItem Header="Copy Image Data" Icon="{StaticResource CopyIcon}" Command="{Binding CopyImageDataCommand}" />
<MenuItem Header="Paste" Icon="{StaticResource PasteIcon}" Command="{Binding PasteImageCommand}" />
</MenuItem>
Notice the 1st 2 items use the same icon, I get something like below
I tried removing the 2nd item,
<MenuItem Header="Edit">
<MenuItem Header="Copy Direct Link" InputGestureText="Ctrl+C" Icon="{StaticResource CopyIcon}" Command="{Binding CopyImageCommand}" />
<!--<MenuItem Header="Copy Image Data" InputGestureText="Ctrl+Alt+C" Icon="{StaticResource CopyIcon}" Command="{Binding CopyImageDataCommand}" />-->
<MenuItem Header="Paste" InputGestureText="Ctrl+P" Icon="{StaticResource PasteIcon}" Command="{Binding PasteImageCommand}" />
</MenuItem>
then I got something like
How can I reuse Icons?
See this question
An Image can only have one parent so it will be moved from the first MenuItem to the second. You can add the x:Shared attribute like this
<Window.Resources>
<Image x:Key="CopyIcon" x:Shared="False" Source="..." />
</Window.Resources>
From msdn
x:Shared Attribute
When set to false, modifies WPF
resource-retrieval behavior so that
requests for the attributed resource
create a new instance for each request
instead of sharing the same instance
for all requests.
You're most likely declaring CopyIcon as Image type in your resource, something like this:
<Window.Resources>
<Image x:Key="CopyIcon" Source="yourcopyicon.ico"/>
</Window.Resources>
So, the root cause of the problem is, Image is a visual element, since it derives from FrameworkElement (which is a visual element), and a visual element cannot have more than one parent at the same time. That is why the first MenuItem is not showing the icon, since the second MenuItem reset the parent of CopyIcon, making itself parent of the CopyIcon.
Hope this explanation is helpful to you. Now follow what Meleak has said in his response. :-)
Try the following:
<MenuItem Header=“Paste“ >
<MenuItem.Icon><Image Height=“16“ Width=“16“ Source=“paste.jpg“ /></MenuItem.Icon>
</MenuItem>

Problems with RichTextBox.Selection and TextSelection.ApplyPropertyValue

I'm trying to create a text editor in WPF using a RichTextBox.
My problem is with changing the font size of my text. My code works as intended in every case, except when the cursor is inside a word. In this case it should not change the font size of anything, except the font size of the text to come if the user writes anything. The problem is that for some reason TextSelection.ApplyPropertyValue(RichTextBox.FontSizeProperty, value) changes the font size of the whole word when the cursor is inside a word.
This is my eventHandler:
private void fontSizeBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
string value = (string)comboBox.SelectedValue;
if (comboBox.IsDropDownOpen)
{
TextSelection text = textBoxMain.Selection;
richTextBox.Focus();
text.ApplyPropertyValue(RichTextBox.FontSizeProperty, value);
}
}
And I cannot use something like adding !text.Text.IsEmpty inside the if statement, because I still need to be able to change the font size for text to be written.
I have found similar questions on StackOverFlow, but none with an actual working answer.
Edit: Added XAML
<Window x:Class="MathEdit.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:MathEdit"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.CommandBindings>
<CommandBinding Command="Open" Executed="OpenCommandBinding_Executed"></CommandBinding>
<CommandBinding Command="Save" Executed="SaveCommandBinding_Executed"></CommandBinding>
<CommandBinding Command="SaveAs" Executed="SaveAsCommandBinding_Executed"></CommandBinding>
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="O" Modifiers="Control" Command="Open"></KeyBinding>
<KeyBinding Key="S" Modifiers="Control" Command="Save"></KeyBinding>
<KeyBinding Key="S" Modifiers="Control+Alt" Command="SaveAs"></KeyBinding>
</Window.InputBindings>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Header="_New" InputGestureText="Ctrl+N" />
<MenuItem Header="_Open" InputGestureText="Ctrl+O" Command="Open"/>
<MenuItem Header="_Save" InputGestureText="Ctrl+S" Command="Save"/>
<MenuItem Header="_Save As" InputGestureText="Ctrl+Alt+S" Command="SaveAs"/>
<Separator />
<MenuItem Header="_Exit" InputGestureText="Alt+F4" />
</MenuItem>
<MenuItem Header="_Tools">
<MenuItem Header="_Check if toby = on" IsCheckable="false" IsChecked="True" Click="MenuItem_Click" />
<MenuItem Header="_Settings" Click="MenuItem_Click_2" IsCheckable="True" />
<MenuItem Header="_Add formula" x:Name="menuItemAdd" Click="MenuItem_Add_Click" />
</MenuItem>
<ComboBox x:Name="fontSizeBox" Width="40" SelectedValuePath="Content" SelectionChanged="fontSizeBox_SelectionChanged" SelectedIndex="2">
<ComboBoxItem Content="5"/>
<ComboBoxItem Content="12"/>
<ComboBoxItem Content="16"/>
<ComboBoxItem Content="20"/>
</ComboBox>
</Menu>
<Grid x:Name="gridParent">
<RichTextBox x:Name="richTextBox" AcceptsReturn="True" SelectionChanged="textBoxMain_SelectionChanged" />
</Grid>
</DockPanel>
This simple application of a property value to a no-text selection is not possible. Look at what you get when you apply it to a real selection: Say you have a text "hello brave new world". The document inside the RTB looks like this (simplified)
<FlowDocument>
<Paragraph>
<Run>hello brave new world</Run>
</Paragraph>
</FlowDocument>
When you select "brave" and change the font size (or anything else), the document changes to
<FlowDocument>
<Paragraph>
<Run>hello </Run>
<Run FontSize="20">brave</Run>
<Run> new world</Run>
</Paragraph>
</FlowDocument>
An attribute has to be applied to some text; there is no way to change "nothing", as you requested. If you want to achieve what to me looks closest to your requirement, you will have to split the document yourself - when the selection is empty - and create an empty run with the desired font size. So the above example would look like this (assuming, the caret is positioned before "brave"):
<FlowDocument>
<Paragraph>
<Run>hello </Run>
<Run FontSize="20"></Run>
<Run>brave new world</Run>
</Paragraph>
</FlowDocument>
As this leaves endless possibilities to end up with an infinite number of "empty" Runs, I would advise to revise your requirement.

how to find out which child of a WPF container the contextmenu was opened for?

Because ToolbarTray does not support proper ItemsSource binding I'm doing things in code behind. Namely filling the tray. How can I tell which toolbar the contextmenu was opened for (with CommandParameter)?
<UserControl.Resources>
<ContextMenu x:Key="ToolbarContextMenu">
<MenuItem Header="Move to top" Command="{ui:CommandHandler MoveToTop}" />
<MenuItem Header="Move to left" Command="{ui:CommandHandler MoveToLeft}" />
<MenuItem Header="Make float" Command="{ui:CommandHandler MakeFloat}" />
</ContextMenu>
</UserControl.Resources>
<ToolBarTray x:Name="MainToolbarTray" Orientation="{Binding Orientation}" ContextMenu="{StaticResource ToolbarContextMenu}"/>
In example above I use a toolkit where commands in ViewModel are decorated with attribute and in xaml command can be defined like this.
(Not the same as suggested. I don't want to find ToolbarTray, but the Toolbar)
EDIT: I just assigned the ContextMenu to Toolbar in code behind and used PlacementTarget as suggested.

Why isnt my WPF menuItem Icon showing?

I can see my Icon in Designer View, but when I run the program it disappears. What am i missing?
EDIT: The Icon itself is 25 by 25 pixels
<DockPanel>
<Menu DockPanel.Dock="Top" HorizontalAlignment="Right" Background="Transparent">
<MenuItem Header="Help">
<MenuItem.Icon>
<Image Source="Resources/Help.png" />
</MenuItem.Icon>
<MenuItem Header="About" />
<MenuItem Header="Update TechTools" />
</MenuItem>
</Menu>
</DockPanel>
You need to set properties on your Help.png file. Righ-click on it, select properties. You want Build action to "Content" and Copy to output directory either Copy Always or Copy if Newer.
You can also consider setting it as Resource, which will embedd it in the program itself.

MenuItem command called when clicking IsCheckable checkbox

My XAML:
<MenuItem Command="{Binding ShowRequestsCommand}" HorizontalAlignment="Stretch" IsCheckable="True" IsChecked="{Binding ShowUrgentEvaluationRequestNotification, Source={x:Static Properties:Settings.Default}, Mode=TwoWay}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<Border Background="Red" CornerRadius="5" Padding="3,1,3,1" Margin="1,1,5,1" HorizontalAlignment="Left" MinWidth="18"></Border>
<TextBlock>Beställningshanteraren</TextBlock>
</StackPanel>
</MenuItem.Header>
</MenuItem>
So it's a MenuItem with some stuff in the header, it is checkable, and that value is supposed to have some functionality elsewhere, it also has a command.
My problem is that when you click the checkbox, the command is called, which is not my intention, and it seems wrong for any situation honestly. You should be able to click the checkbox without activating whatever the MenuItem is supposed do do. I get the same result if I add a click event on the menuitem instead.
Why does WPF work like this? Is there a workaround?

Categories

Resources