wpf - VsBrush 在 WPF ResourceDictionary 中不起作用

标签 wpf visual-studio xaml contenttemplate

tl;博士

问题描述

首先,我是 WPF 新手,现在我几乎不知道自己在做什么......

我正在开发一个 Visual Studio 2013 扩展,我在其中创建一个自定义工具窗口。由于 WPF 控件不会从父级(即 Visual Studio 主窗口)继承主题,因此您必须手动继承。

我读到我应该使用 Microsoft.VisualStudio.Shell.VsBrushesMicrosoft.VisualStudio.PlatformUI.EnvironmentColors类,因为它们定义了 Visual Studio shell 主题特定常量。 ( See example here. ) 只要我在 Style 中使用它,这一切都很好。标签。

但是,微软的Menu and MenuItem ControlTemplate Example解释如何使用 <ContentTemplate> 制作正确的 MenyItem 模板。 问题是,VsBrush 和环境颜色都无法在 <ContentTemplate> 范围内工作。 。当我为 <GradintStop> 设置颜色时,要么出现通用异常提示(没有详细信息,问题是什么),或者用户界面只是挂起,甚至无法加载。在后一种情况下,当我破坏应用程序时,我总是会进入 MS.Win32.UnsafeNativeMethods.GetMessageW()功能。

问题

  1. 有人可以解释一下我做错了什么以及为什么我不能使用 VsBrushesEnvironmentColors我的类(class)<ContentTemplate>
  2. 如何使用建议的 <ContentTemplate> 正确设置我的 Visual Studio 扩展的样式格式?

尝试解决问题

  1. 我检查了整个包的构造函数,VsBrushes 的颜色常量可以获取类。只有在构造函数之后,UI 才会挂起,因此 VsBrushes值必须在处理 XAML 时初始化。
  2. 如上所述,不使用 <ControlTemplate>可以使用常量。
  3. 调查了异常:当解析器尝试解释 <GradientStop> 的 Color 属性时抛出该异常。标签。没有解释到底是什么失败了。 (过了一会儿——随着代码发生了一些变化——异常停止了,UI 开始挂起。)
  4. 如果我更改 LinearGradientBrushSolidColorBrush问题仍然存在(当然这次的异常略有不同):“设置属性‘System.Windows.Media.SolidColorBrush.Color’引发了异常。
  5. 问题不是 <MenuItem>具体的。可以使用 <Button> 进行复制我猜想可以使用任意 WPF 控件。

来源

这是我用来定义 MenuItems 样式的代码:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:vsShell="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.12.0"
                    xmlns:vsUI="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.12.0">
    <Color x:Key="MyColor">#FFFFFF00</Color>
    <Style x:Key="{x:Type Menu}" TargetType="{x:Type Menu}">
        <Setter Property="OverridesDefaultStyle" Value="True" />
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Menu}">
                    <Border BorderThickness="1">
                        <Border.BorderBrush>
                            <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
                                <LinearGradientBrush.GradientStops>
                                    <GradientStopCollection>
                                        <GradientStop Color="{DynamicResource MyColor}" Offset="0.0" />
                                        <GradientStop Color="{DynamicResource {x:Static SystemColors.ActiveBorderColorKey}}" Offset="0.1" />
                                        <GradientStop Color="#FF00FF00" Offset="0.5" />
                                        <!-- The following 3 do not work -->
                                        <GradientStop Color="{DynamicResource {x:Static vsUI:EnvironmentColors.AccentBorderBrushKey}}" Offset="0.8" />
                                        <GradientStop Color="{DynamicResource {x:Static vsShell:VsBrushes.AccentBorderKey}}" Offset="0.8" />
                                        <GradientStop Color="{DynamicResource VsBrush.AccentBorder}" Offset="1.0" />
                                    </GradientStopCollection>
                                </LinearGradientBrush.GradientStops>
                            </LinearGradientBrush>
                        </Border.BorderBrush>
                        <Border.Background>
                            <LinearGradientBrush EndPoint="0,0.5" StartPoint="1,0.5">
                                <GradientStop Color="Blue" Offset="0" />
                                <GradientStop Color="Blue" Offset="1" />
                            </LinearGradientBrush>
                        </Border.Background>
                        <StackPanel ClipToBounds="True" Orientation="Horizontal" IsItemsHost="True" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

调用堆栈

这是进程“挂起”的地方:

[Managed to Native Transition]  
>   WindowsBase.dll!MS.Win32.UnsafeNativeMethods.GetMessageW(ref System.Windows.Interop.MSG msg, System.Runtime.InteropServices.HandleRef hWnd, int uMsgFilterMin, int uMsgFilterMax) Line 566  C#
WindowsBase.dll!System.Windows.Threading.Dispatcher.GetMessage(ref System.Windows.Interop.MSG msg, System.IntPtr hwnd, int minMessage, int maxMessage) Line 391 C#
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Line 979  C#
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) Line 961  C#
WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() Line 1059 C#
Microsoft.VisualStudio.Shell.12.0.dll!Microsoft.Internal.VisualStudio.PlatformUI.BackgroundDispatcher.ThreadProc(object arg)    Unknown
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state)    Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart(object obj)  Unknown

最佳答案

分辨率

以下所有 3 行都会导致编译错误,因为编译器需要 Color但我给了它 Brush相反。

<GradientStop Color="{DynamicResource {x:Static vsUI:EnvironmentColors.AccentBorderBrushKey}}" Offset="0.8" />
<GradientStop Color="{DynamicResource {x:Static vsShell:VsBrushes.AccentBorderKey}}" Offset="0.8" />
<GradientStop Color="{DynamicResource VsBrush.AccentBorder}" Offset="1.0" />

我应该使用<GradientStop Color="{DynamicResource {x:Static vsUI:EnvironmentColors.AccentBorderColorKey}}" Offset="0.8" /> (请注意,我使用 AccentBorderColorKey 而不是 AccentBorderBrushKey。)

XAML 正在解析字符串并尝试解释它,这导致了一个简单的事实:XAML 是无类型的(一切都是字符串)。由于错误消息(“设置属性“System.Windows.Media.LinearGradientBrush.Color”抛出异常。)并不是真正的对话,它并不能真正帮助您理解您做错了什么。

经验教训

如果编译器没有为您执行此操作(或者没有告诉您这是导致问题的原因),请尝试手动检查类型。

关于wpf - VsBrush 在 WPF ResourceDictionary 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28372377/

相关文章:

c# - 了解使用 Windows native WPF 客户端进行 ADFS 登录

wpf - WPF中的单元测试路由事件

c# - 数据网格和列数

visual-studio - Visual Studio 中 Eclipse 的 Ctrl+单击?

xaml - ListView SelectedItem 与 Xamarin 表单和 ReactiveUI 问题绑定(bind)

wpf - WPF(XAML)中无参数构造函数的作用

c# - 对面向 .NET6 的 WPF Windows 应用程序使用 Nunit 测试时出错

visual-studio - 为整个解决方案运行自定义工具

c# - 如何在 Visual Studio 中为自定义配置文件添加配置转换?

.net - 如何从资源字典继承/扩展样式?