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.
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.
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();
}
}
To inverted correctly, the icon of Light theme should be as another Visual Studio icons (with gray rim around, like this ).
..\Microsoft Visual Studio 11.0\VSSDK\VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.VisualStudio.Shell.11.0.dll
contains very few control's and even they are limited to stuff you find in the StartPage and so on. A much more extensive set of controls exist inMicrosoft Visual Studio 11.0\Common7\IDE\en\Microsoft.VisualStudio.Shell.UI.Internal.resources.dll
but only few from them can be be referenced via DynamicResource to your package project. – ImitableInternal.resources.dll
and copy it out into your own ResourceDictionary for use in all your package projects. That way even if something is switched in VS via a service-pack, your UI ain't going to get broken. It does seem pretty poor to not be able to get the Style's directly or by specifying xaml control's in the` *.vsct` files. – Imitable