Visual Studio 2012 использует настраиваемые элементы управления WPF. Вы можете убедиться в этом самостоятельно с помощью Snoop. Визуальное дерево WPF Visual Studio 2012 содержит такие элементы управления, как Microsoft.VisualStudio.PlatformUI.VsButton, Microsoft.VisualStudio.PlatformUI.Shell.Controls.TabGroupControl, Microsoft.VisualStudio.PlatformUI.SearchControl
. К сожалению, эти элементы управления не документированы, и их сложно или невозможно использовать повторно. Вы можете только просматривать стили сложных элементов и реализовывать аналогичные в своем коде.
Я создаю аналогичные элементы управления на основе коллекции Winfried Lötzsch (теперь он включен в инструментарий MahApps.Metro). Я также видел другую коллекцию привлекательных элементов. Это тоже может быть полезно.
Для реализации поддержки тем Visual Studio я использую ресурсы из Microsoft.VisualStudio.Shell.VsBrushes/VsColors
и собственные цвета. Чтобы преобразовать значки в текущую тему, я использую следующий код:
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();
}
}
Чтобы инвертировать правильно, значок светлой темы должен быть таким же, как другие значки Visual Studio (с серым ободком вокруг, как этот ).
person
Mikhail Shcherbakov
schedule
08.07.2013
..\Microsoft Visual Studio 11.0\VSSDK\VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.VisualStudio.Shell.11.0.dll
содержит очень мало элементов управления, и даже они ограничены тем, что вы найдете на стартовой странице и так далее. ВMicrosoft Visual Studio 11.0\Common7\IDE\en\Microsoft.VisualStudio.Shell.UI.Internal.resources.dll
существует гораздо более обширный набор элементов управления, но лишь немногие из них могут быть связаны через DynamicResource с вашим пакетным проектом. - person Viv   schedule 09.07.2013Internal.resources.dll
и скопировать их в свой собственный ResourceDictionary для использования во всех ваших проектах пакетов. Таким образом, даже если что-то переключится в VS через сервис-пак, ваш пользовательский интерфейс не сломается. Кажется довольно плохим, что нельзя получить стили напрямую или указать элементы управления xaml в файлах *.vsct. - person Viv   schedule 09.07.2013