VS 2012 扩展中的标准控件 [英] Standard controls in VS 2012 extension

查看:44
本文介绍了VS 2012 扩展中的标准控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在更改公司内部的 VS 扩展以支持 Visual Studio 2012.我正在努力解决的是如何使 UI 动态适应活动的 VS 主题.

I am currently changing a company-internal VS extension to support Visual Studio 2012. What I am struggling with is how to make the UI adapting to the active VS theme dynamically.

我发现了几个颜色/画笔的资源键(Microsoft.VisualStudio.Shell.11.0.dll 中的 VsColors/VsBrushes),我可以轻松地使用它们来更改扩展的基本配色方案.问题是标准控件(文本框、组合框、复选框)具有默认的 WPF 外观,这看起来很奇怪.

I found several resource keys for colors/brushes (VsColors/VsBrushes in Microsoft.VisualStudio.Shell.11.0.dll) that I can easily use to change the basic color scheme of the extension. The problem is that the standard controls (text boxes, combo boxes, check boxes) have the default WPF appearance which looks really weird.

所以问题是:是否有可能使 VS 扩展的 WPF 工具窗口中的标准控件看起来类似于 Visual Studio 中使用的控件?我知道我可以使用控件模板或自定义控件自己完成此操作,但如果可能的话,我真的想避免这种工作.

So the question is: Is there any possibility to make standard controls in a WPF tool window of a VS extension look similar to the ones used in Visual Studio? I am aware that I could do this myself using control templates or custom controls but I really want to avoid this effort if somehow possible.

推荐答案

Visual Studio 2012 使用自定义 WPF 控件.您可以通过 Snoop 自行验证.Visual Studio 2012 的 WPF 可视化树包含诸如 Microsoft.VisualStudio.PlatformUI.VsButton、Microsoft.VisualStudio.PlatformUI.Shell.Controls.TabGroupControl、Microsoft.VisualStudio.PlatformUI.SearchControl 等控件.不幸的是,这些控件没有记录,并且很难或不可能重复使用.您只能查看复杂元素的样式并在代码中实现类似的样式.

Visual Studio 2012 use custom WPF controls. You can verify this yourself by Snoop. WPF visual tree of Visual Studio 2012 contains such controls as Microsoft.VisualStudio.PlatformUI.VsButton, Microsoft.VisualStudio.PlatformUI.Shell.Controls.TabGroupControl, Microsoft.VisualStudio.PlatformUI.SearchControl. Unfortunately, these controls are not documented and are difficult or impossible to reuse. You can only view styles of complex elements and implement similar in your code.

我基于 Winfried Lötzsch 创建了类似的控件集合(现在它包含在 MahApps.Metro 工具包中).我还看到了另一个系列的吸引人的元素.它也可能有用.

I create similar controls base on Winfried Lötzsch collection (now it is included in the MahApps.Metro toolkit). I also saw another collection of attractive elements. It may be useful too.

为了实现对 Visual Studio 主题的支持,我使用了来自 Microsoft.VisualStudio.Shell.VsBrushes/VsColors 的资源和自己的颜色.要将图标转换为当前主题,我使用以下代码:

To implement support for Visual Studio themes, I use resources from Microsoft.VisualStudio.Shell.VsBrushes/VsColors and own colors. To convert icons to current theme, I use following code:

private readonly IVsUIShell5 _vsUIShell5;
private string _currentThemeId;

// cache icons for specific themes: <<ThemeId, IconForLightTheme>, IconForThemeId>
private readonly Dictionary<Tuple<string, BitmapImage>, BitmapImage> _cacheThemeIcons = 
  new Dictionary<Tuple<string, BitmapImage>, BitmapImage>();

protected override BitmapImage GetIconCurrentTheme(BitmapImage iconLight)
{
  Debug.Assert(iconLight != null);
  return _currentThemeId.ToThemesEnum() == Themes.Light ? iconLight : GetCachedIcon(iconLight);
}

private BitmapImage GetCachedIcon(BitmapImage iconLight)
{
  BitmapImage cachedIcon;
  var key = Tuple.Create(_currentThemeId, iconLight);
  if (_cacheThemeIcons.TryGetValue(key, out cachedIcon))
  {
    return cachedIcon;
  }

  var backgroundColor = FindResource<Color>(VsColors.ToolWindowBackgroundKey);
  cachedIcon = CreateInvertedIcon(iconLight, backgroundColor);
  _cacheThemeIcons.Add(key, cachedIcon);
  return cachedIcon;
}

private BitmapImage CreateInvertedIcon(BitmapImage inputIcon, Color backgroundColor)
{
  using (var bitmap = inputIcon.ToBitmapByPngEncoder())
  {
    var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
    var bitmapData = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat);
    var sourcePointer = bitmapData.Scan0;
    var length = Math.Abs(bitmapData.Stride) * bitmap.Height;
    var outputBytes = new byte[length];
    Marshal.Copy(sourcePointer, outputBytes, 0, length);
    _vsUIShell5.ThemeDIBits((UInt32)outputBytes.Length, outputBytes, (UInt32)bitmap.Width,
                            (UInt32)bitmap.Height, true, backgroundColor.ToUInt());
    Marshal.Copy(outputBytes, 0, sourcePointer, length);
    bitmap.UnlockBits(bitmapData);
    return bitmap.ToPngBitmapImage();
  }
}

要正确反转,Light 主题的图标应该是另一个 Visual Studio 图标(周围有灰色边框,像这样 ).

To inverted correctly, the icon of Light theme should be as another Visual Studio icons (with gray rim around, like this ).

这篇关于VS 2012 扩展中的标准控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆