8

私は現在、Visual Studio 2012 をサポートするために社内の VS 拡張機能を変更しています。私が苦労しているのは、アクティブな VS テーマに動的に適応する UI を作成する方法です。

色/ブラシ (Microsoft.VisualStudio.Shell.11.0.dll の VsColors/VsBrushes) のリソース キーがいくつか見つかりました。これを使用して、拡張機能の基本的な配色を簡単に変更できます。問題は、標準のコントロール (テキスト ボックス、コンボ ボックス、チェック ボックス) がデフォルトの WPF の外観を持っていることです。これは非常に奇妙に見えます。

質問は、VS 拡張機能の WPF ツール ウィンドウの標準コントロールを、Visual Studio で使用されているものと似たものにする可能性はありますか? コントロール テンプレートまたはカスタム コントロールを使用して自分でこれを行うことができることは承知していますが、何とかしてこの作業を避けたいと思っています。

4

2 に答える 2

7

Visual Studio 2012 はカスタム WPF コントロールを使用します。これはSnoopで自分で確認できます。Visual Studio 2012 の WPF ビジュアル ツリーには、 などのコントロールが含まれてい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 アイコンのようにする必要があります (この のように、周囲に灰色の縁がありますエラーアイコン)。

于 2013-07-08T09:06:50.577 に答える
1

DLL逆コンパイル

themes/generic.bamlのリソースには、探しMicrosoft.VisualStudio.Shell.12.dllているコントロールのスタイルが含まれている可能性があります。dotPeek を使用しましたが、Baml ファイルを視覚化するためのプラグインがインストールされていません。試すことができるプラグインがいくつかあります。

=P を介して抽出されたスタイルを使用することがライセンスで許可されているかどうかを確認する必要があります。

于 2013-07-08T09:02:04.730 に答える