我想在鼠标左键单击的wpf / c#应用程序中有一个上下文菜单。我知道这是一种不寻常的行为,但在这种非常具体的情况下,它是必需的。 这是xaml文件(缩减为相关部分):
<Window x:Class="_ContextMenuText.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:_ContextMenuText"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300">
<Window.Resources>
<ResourceDictionary>
<Color x:Key="NormalBrushGradient1">#FFAF231E</Color>
<Color x:Key="NormalBrushGradient2">#FF9F231E</Color>
<Color x:Key="NormalBrushGradient3">#FF8F231E</Color>
<Color x:Key="NormalBrushGradient4">#FF601818</Color>
<Color x:Key="NormalBorderBrushGradient1">#FFBBBBBB</Color>
<Color x:Key="NormalBorderBrushGradient2">#FF737373</Color>
<Color x:Key="NormalBorderBrushGradient3">#FF646464</Color>
<Color x:Key="NormalBorderBrushGradient4">#FF000000</Color>
<Color x:Key="WindowBackgroundBrushGradient1">#FF8496AA</Color>
<Color x:Key="WindowBackgroundBrushGradient2">#FF414141</Color>
<LinearGradientBrush x:Key="NormalBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{StaticResource NormalBrushGradient1}"
Offset="0" />
<GradientStop Color="{StaticResource NormalBrushGradient2}"
Offset="0.33" />
<GradientStop Color="{StaticResource NormalBrushGradient3}"
Offset="0.66" />
<GradientStop Color="{StaticResource NormalBrushGradient4}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="WindowBackgroundBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{StaticResource WindowBackgroundBrushGradient1}" />
<GradientStop Color="{StaticResource WindowBackgroundBrushGradient2}"
Offset="1" />
</LinearGradientBrush>
<Style TargetType="{x:Type ContextMenu}">
<Setter Property="Background" Value="{DynamicResource WindowBackgroundBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource NormalBorderBrush}"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Grid>
<Border Margin="1" x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"/>
<StackPanel Background="{TemplateBinding Background}" IsItemsHost="True" ClipToBounds="True" Orientation="Vertical"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="Border"/>
<Setter Property="BorderBrush" Value="{DynamicResource DisabledBorderBrush}" TargetName="Border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{DynamicResource TextBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<ControlTemplate.Resources>
<Storyboard x:Key="HighlightedOn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HighlightedOff">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="17" Width="Auto" SharedSizeGroup="MenuItemIconColumnGroup"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGTColumnGroup"/>
<ColumnDefinition Width="14"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Grid.ColumnSpan="4" Background="{DynamicResource NormalBrush}" Opacity="0" x:Name="border"/>
<ContentPresenter Margin="4,0,6,0" x:Name="Icon" VerticalAlignment="Center" ContentSource="Icon"/>
<Grid Visibility="Hidden" Margin="4,0,6,0" x:Name="GlyphPanel" VerticalAlignment="Center">
<Path x:Name="GlyphPanelpath" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}" Data="M0,2 L0,4.8 L2.5,7.4 L7.1,2.8 L7.1,0 L2.5,4.6 z" FlowDirection="LeftToRight"/>
</Grid>
<ContentPresenter Grid.Column="1" Margin="{TemplateBinding Padding}" x:Name="HeaderHost" RecognizesAccessKey="True" ContentSource="Header"/>
<Grid Grid.Column="3" Margin="4,0,6,0" x:Name="ArrowPanel" VerticalAlignment="Center">
<Path x:Name="ArrowPanelPath" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}" Data="M0,0 L0,8 L4,4 z"/>
</Grid>
<Popup IsOpen="{Binding Path=IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" x:Name="SubMenuPopup" Focusable="false" AllowsTransparency="true" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" VerticalOffset="-3">
<Grid x:Name="SubMenu">
<Border x:Name="SubMenuBorder" Background="{DynamicResource WindowBackgroundBrush}" BorderBrush="{DynamicResource SolidBorderBrush}" BorderThickness="1"/>
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Grid>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Margin" Value="0,1,0,1"/>
<Setter Property="Padding" Value="6,3,6,3"/>
<Setter Property="Grid.IsSharedSizeScope" Value="true"/>
<Setter Property="Placement" Value="Bottom" TargetName="SubMenuPopup"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Margin" Value="0,1,0,1"/>
<Setter Property="Padding" Value="6,3,6,3"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="Padding" Value="0,2,0,2"/>
<Setter Property="Grid.IsSharedSizeScope" Value="true"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="Padding" Value="0,2,0,2"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
</Trigger>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter Property="PopupAnimation" Value="None" TargetName="SubMenuPopup"/>
</Trigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Visibility" Value="Visible" TargetName="GlyphPanel"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
</Trigger>
<Trigger Property="AllowsTransparency" SourceName="SubMenuPopup" Value="true">
<Setter Property="Margin" Value="0,0,3,3" TargetName="SubMenu"/>
<Setter Property="SnapsToDevicePixels" Value="true" TargetName="SubMenu"/>
<Setter Property="BitmapEffect" Value="{DynamicResource PopupDropShadow}" TargetName="SubMenuBorder"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="true">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource HighlightedOff}" x:Name="HighlightedOff_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource HighlightedOn}"/>
</Trigger.EnterActions>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Window.Resources>
<Label
Content="Test"
Height="30"
Width="50"
Name="TestLabel"
Background="Azure"
Foreground="Black"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
MouseLeftButtonUp="TestLabel_MouseLeftButtonUp"/>
代码(C#):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace _ContextMenuText
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ContextMenu cont = new ContextMenu();
cont.Style = this.FindResource(typeof(ContextMenu)) as Style;
MenuItem mni = new MenuItem();
AddStyleToItem(mni);
mni.Header = "item1";
cont.Items.Add(mni);
MenuItem mni1 = new MenuItem();
AddStyleToItem(mni);
mni1.Header = "item2";
mni.Items.Add(mni1);
MenuItem mni2 = new MenuItem();
AddStyleToItem(mni);
mni2.Header = "item22";
mni.Items.Add(mni2);
TestLabel.ContextMenu = cont;
}
private void AddStyleToItem(MenuItem item)
{
item.Style = this.FindResource(typeof(MenuItem)) as Style;
}
private void TestLabel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
TestLabel.ContextMenu.IsOpen = true;
}
}
}
如果我启动程序并首先用鼠标左键单击标签,则上下文菜单的样式设置不正确:
如果通过单击鼠标右键打开上下文菜单,则会正确显示上下文菜单:
关键是在单击鼠标右键打开上下文菜单后,单击鼠标左键打开它时样式也很好。 似乎单击鼠标右键时会进行一些初始化。我一直在寻找模拟鼠标右键单击的方法,但这并没有成功。如果我按下鼠标右键单击代码,则不会进行此类初始化。上下文菜单显示正确。我试图在代码中删除样式的赋值:
cont.Style = this.FindResource(typeof(ContextMenu)) as Style;
这会导致几乎相同的错误行为。首先通过鼠标右键单击打开上下文菜单时,只有第一个设计是不同的:
有没有人可以帮助我?非常感谢!
答案 0 :(得分:1)
您需要将ResourceDictionary的内容移动到App.xaml到Application.Resources - 然后它将开始工作并在Window Resources中删除ResourceDictionary。如果适合你,请告诉我。