65.9K
CodeProject 正在变化。 阅读更多。
Home

Visual Studio IDE 的集成颜色选择器 - VSPackage(AddIn)

starIconstarIconstarIconstarIconstarIcon

5.00/5 (13投票s)

2014 年 6 月 1 日

CPOL

6分钟阅读

viewsIcon

51136

downloadIcon

1217

Visual Studio IDE 的颜色选择器工具,VSPackage 演练

引言

如果您是 Web 开发人员或 UI 设计师,并且主要使用 Visual Studio 完成日常任务,那么 Visual Studio 集成颜色选择器将非常有用。在本文中,我将向您介绍 Color Picker AddIn(或插件)的演练。

如果您想获取最新版本的 Color Picker AddIn,请 点击此处

Integrated Color Picker for Visual Studio

背景

有时,我需要进行 UI 设计,例如使用 CSS 和/或 HTML 标记更改颜色或对齐方式,并且我发现直接从 IDE 获取颜色选择器非常困难。因此,我考虑为 Visual Studio 编写自己的颜色选择器插件。我将在此分享初始代码,以便您也可以尝试一下。

Using the Code

我在这款颜色选择器工具中用到了一些 Extended WPF Toolkit 的组件。在开始之前,最好先阅读一下文章《使用 Extended WPF Toolkit 的 Color Canvas 和 Color Picker》,这样您就能了解 Extended WPF Toolkit 的 Color Canvas 和 Color Picker 的实现。

扩展 Visual Studio 有多种方法。最常见的三种是:自动化、VSPackage 扩展和 Managed Extensibility Framework (MEF) 扩展。Visual Studio 2013 中已弃用 Visual Studio 加载项。您应该将您的加载项升级为 VSPackage 扩展。

我将使用 Visual Studio Package (VSPackage) 来创建此 AddIn。您可能对使用 Visual Studio Add-In 项目模板创建的 Web Search 感兴趣。

要开始开发 Visual Studio 扩展,您首先需要从 Visual Studio 2013 SDK 下载网站下载并安装 Visual Studio SDK。它兼容 Visual Studio 2013 Professional、Premium 或 Ultimate 版本。我使用的是 Visual Studio 2013。如果您使用的是不同版本,请确保您已安装正确版本的 Visual Studio SDK。

新建项目

Integrated Color Picker for Visual Studio - Visual Studio Package

在这里,我选择新建项目 -> 其他项目类型 -> Extensibility,然后选择 Visual Studio Package 项目模板,将项目名称命名为 Color Picker。现在点击确定继续。

注意:如果您在其他项目类型下看不到 Visual Studio Package,则必须安装 Visual Studio SDK。有关 Visual Studio SDK 的更多信息,请参阅 Visual Studio 扩展概述。要查找如何下载 Visual Studio SDK,请参阅 MSDN 网站上的 Visual Studio 扩展开发中心

在 Visual Studio Package 向导中使用以下选项。

第 1 页,共 7 页 - 选择编程语言

选择您的语言为 Visual C#,并生成一个新的密钥文件来签名程序集。

第 2 页,共 7 页 - 基本 VSPackage 信息

我已按上图所示输入基本 VSPackage 信息。

第 3 页,共 7 页 - 选择 VSPackage 选项

选择菜单命令。默认情况下,这将在工具菜单下添加一个菜单项。

第 4 页,共 7 页 - 命令选项

将命令名称更改为“Color Picker”。

第 7 页,共 7 页 - 选择测试项目选项

您应该选择集成测试项目和单元测试项目,但目前请取消选中它们。:)

点击**完成**。

Visual Studio 现在将为您创建基础项目。现在我们有了解决方案文件,下面的屏幕截图显示了解决方案文件。

让我们运行(F5)此应用程序,看看我们现在得到了什么。

运行应用程序后,我们可以在 Visual Studio 实验实例中检查 AddIn 的功能。如果您在实验实例中点击“工具”菜单,您将看到“Color Picker”命令,如下所示。

点击“Color Picker”菜单即可看到默认代码库的运行效果。

想知道我们是如何在工具菜单下获得Color Picker 菜单的吗?在 ColorPicker.vsct 文件中,我们将菜单组的父级指定为工具菜单。

<Group guid="guidColorPickerCmdSet" id="MyMenuGroup" priority="0x0600">
  <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
</Group>

菜单项名称和图标在<Button>中指定。

<Button guid="guidColorPickerCmdSet" id="cmdidColorPicker" priority="0x0100" type="Button">
  <Parent guid="guidColorPickerCmdSet" id="MyMenuGroup" />
  <Icon guid="guidImages" id="bmpPic1" />
  <Strings>
    <ButtonText>Color Picker</ButtonText>
  </Strings>
</Button>

图标在<Bitmaps><Bitmap>中指定,而 GuidSymbols 定义在<Symbols>下。使用 source.extension.vsixmanifest 文件来更改图标和将在扩展管理器窗口中显示的预览图像。此文件可用于更改目标 Visual Studio 版本和框架等。

ColorPickerPackage.cs 用于添加菜单项及其功能。下面 ColorPickerPackage.cs 中的代码用于将菜单项添加到 IDE 菜单。

/////////////////////////////////////////////////////////////////////////////
// Overridden Package Implementation
#region Package Members

/// <summary>
/// Initialization of the package; this method is called 
/// right after the package is sited, so this is the place
/// where you can put all the initialization code that rely on 
/// services provided by VisualStudio.
/// </summary>
protected override void Initialize()
{
    Debug.WriteLine (string.Format(CultureInfo.CurrentCulture, 
                     "Entering Initialize() of: {0}", this.ToString()));
    base.Initialize();

    // Add our command handlers for menu (commands must exist in the .vsct file)
    OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) 
                                as OleMenuCommandService;
    if ( null != mcs )
    {
        // Create the command for the menu item.
        CommandID menuCommandID = new CommandID(GuidList.guidColorPickerCmdSet, 
                                  (int)PkgCmdIDList.cmdidColorPicker);
        MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID );
        mcs.AddCommand( menuItem );
    }
}
#endregion

点击Color Picker 菜单时,将调用 MenuItemCallback。下面是我提供的 MenuItemCallback 的默认实现,它目前会显示一个消息框。

/// <summary>
/// This function is the callback used to execute a command when the menu item is clicked.
/// See the Initialize method to see how the menu item is associated to this function using
/// the OleMenuCommandService service and the MenuCommand class.
/// </summary>
private void MenuItemCallback(object sender, EventArgs e)
{
    // Show a Message Box to prove we were here
    IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
    Guid clsid = Guid.Empty;
    int result;
    Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox(
                0,
                ref clsid,
                "ColorPicker",
                string.Format(CultureInfo.CurrentCulture, 
                              "Inside {0}.MenuItemCallback()", this.ToString()),
                string.Empty,
                0,
                OLEMSGBUTTON.OLEMSGBUTTON_OK,
                OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                OLEMSGICON.OLEMSGICON_INFO,
                0,        // false
                out result));
}

现在我们来讨论实际的颜色选择器实现。由于我们利用了 Extended WPF Toolkit 的组件,因此我们需要在应用程序中引用该工具包的二进制文件。

我将从“Extended WPF Toolkit Binaries”中添加“Xceed.Wpf.Toolkit.dll”的引用。有关添加引用的详细步骤,请阅读文章《使用 Extended WPF Toolkit 的 Color Canvas 和 Color Picker》。

添加对“Xceed.Wpf.Toolkit.dll”的引用后,我们需要添加一个 WPF 窗口来托管颜色选择器的功能。

我将 WPF 窗口命名为 ColorPickerUI.xaml

首先,我将在新添加的窗口中添加一个 xmlns,这将使我们能够使用 Extended WPF Toolkit 中的控件。

<Window x:Class="ShemeerNS.ColorPicker.ColorPickerUI"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        Title="ColorPickerUI" Height="300" Width="300">
    <Grid>
        
    </Grid>
</Window>

然后,我为<Grid>添加了三行,这些行将容纳实际的控件。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <!--Row-1 Color Canvas-->
    <!--Row-2 Color Picker-->
    <!--Row-3 Copy Color Code-->
</Grid>

现在我添加了第 1 行(颜色画布)

<GroupBox 
            Grid.Row="0"
            Header="Color Canvas:"
            HorizontalAlignment="Stretch">
    <xctk:ColorCanvas x:Name="_colorCanvas"                                             
                    VerticalAlignment="Top"
                    HorizontalAlignment="Stretch" />
</GroupBox>

第 2 行如下(颜色选择器)

<GroupBox 
    Grid.Row="1"
    Header="Color Picker:"
    HorizontalAlignment="Stretch">

    <xctk:ColorPicker x:Name="_colorPicker" VerticalAlignment="Top" 
          DisplayColorAndName="True" ShowAdvancedButton="False" 
                ShowAvailableColors="True" ShowRecentColors="False" 
                ShowStandardColors="True"
                ShowDropDownButton="True" Width="278" />
</GroupBox>

第 3 行如下(复制颜色代码)

<GroupBox 
            Grid.Row="2"
            Header="Get Color Code:"
            HorizontalAlignment="Stretch" Margin="0,2,0,5">
    <Grid  >
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto"  />
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" Grid.Row="0"
                    Text="Alpha: " HorizontalAlignment="Left" 
                    Width="36" Margin="0,5,0,0"/>
        <CheckBox Grid.Column="1"
                    Grid.Row="0"
                    x:Name="_usingAlphaChannel"
                    IsChecked="{Binding ElementName=_colorCanvas, 
                    Path=UsingAlphaChannel, Mode=TwoWay}" Margin="0,5,0,0"/>
        <TextBlock Grid.Column="0"
                    Grid.Row="2"
                    Text="HEX: " Margin="0,5,0,0"/>
        <TextBox Grid.Column="1" x:Name="_hexvalue" BorderBrush="#FF617585"
                Grid.Row="2"
                IsReadOnly="True"
                Text="{Binding ElementName=_colorCanvas, 
                Path=HexadecimalString}" Margin="0,5,0,0"  />

        <Button x:Name="btnCopy" Grid.Column="2"
                Grid.Row="2" Margin="2,0,0,0" ToolTip="Copy">Copy                  
        </Button>                
    </Grid>
</GroupBox>

为了使颜色画布和颜色选择器显示相同的颜色,我对这两个控件都添加了 SelectedColorChanged 方法,如下所示。

SelectedColorChanged="_colorCanvas_SelectedColorChanged"

SelectedColorChanged="_colorPicker_SelectedColorChanged"

事件定义在 xaml.cs 中添加,如下所示。

private void _colorCanvas_SelectedColorChanged
    (object sender, RoutedPropertyChangedEventArgs<System.Windows.Media.Color> e)
{
    _colorPicker.SelectedColor = _colorCanvas.SelectedColor;
}
private void _colorPicker_SelectedColorChanged
    (object sender, RoutedPropertyChangedEventArgs<Color> e)
{
    _colorCanvas.SelectedColor = _colorPicker.SelectedColor;
}

上面的代码将在发生任何颜色变化时将两个控件的选定颜色设置为相同。为了通过“复制”按钮复制颜色代码,我为复制按钮添加了 click 事件,如下所示。

Click="btnCopy_Click"

定义已添加到 xaml.cs 文件中,如下所示。

private void btnCopy_Click(object sender, RoutedEventArgs e)
{
    Clipboard.SetText(_colorCanvas.HexadecimalString);
}

请确保您已在此项目中引用了 System.xaml

完整的源代码如下。完整的可运行源代码已附在此文章中。

ColorPickerUI.xaml

<Window x:Class="ShemeerNS.ColorPicker.ColorPickerUI"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        Title="Color Picker" Height="430" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <GroupBox 
            Grid.Row="0"
            Header="Color Canvas:"
            HorizontalAlignment="Stretch">
            <xctk:ColorCanvas x:Name="_colorCanvas"                                             
                    VerticalAlignment="Top"
                    HorizontalAlignment="Stretch" 
                    SelectedColorChanged="_colorCanvas_SelectedColorChanged"/>
        </GroupBox>
        <GroupBox 
    Grid.Row="1"
    Header="Color Picker:"
    HorizontalAlignment="Stretch">

            <xctk:ColorPicker x:Name="_colorPicker" 
             VerticalAlignment="Top" DisplayColorAndName="True" 
             ShowAdvancedButton="False" 
                ShowAvailableColors="True" 
                ShowRecentColors="False" ShowStandardColors="True"
                ShowDropDownButton="True" Width="278" 
                SelectedColorChanged="_colorPicker_SelectedColorChanged" />
        </GroupBox>

        <GroupBox 
            Grid.Row="2"
            Header="Get Color Code:"
            HorizontalAlignment="Stretch" Margin="0,2,0,5">
            <Grid  >
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto"  />
                </Grid.ColumnDefinitions>

                <TextBlock Grid.Column="0" Grid.Row="0"
                    Text="Alpha: " HorizontalAlignment="Left" 
                    Width="36" Margin="0,5,0,0"/>
                <CheckBox Grid.Column="1"
                    Grid.Row="0"
                    x:Name="_usingAlphaChannel"
                    IsChecked="{Binding ElementName=_colorCanvas, 
                    Path=UsingAlphaChannel, Mode=TwoWay}" Margin="0,5,0,0"/>
                <TextBlock Grid.Column="0"
                    Grid.Row="2"
                    Text="HEX: " Margin="0,5,0,0"/>
                <TextBox Grid.Column="1" x:Name="_hexvalue" BorderBrush="#FF617585"
                Grid.Row="2"
                IsReadOnly="True"
                Text="{Binding ElementName=_colorCanvas, Path=HexadecimalString}" 
                Margin="0,5,0,0"  />

                <Button x:Name="btnCopy" Grid.Column="2"
                Grid.Row="2" Margin="2,0,0,0" 
                ToolTip="Copy" Click="btnCopy_Click">Copy
                </Button>
            </Grid>
        </GroupBox>
    </Grid>
</Window>

ColorPickerUI.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace ShemeerNS.ColorPicker
{
    /// <summary>
    /// Interaction logic for ColorPickerUI.xaml
    /// </summary>
    public partial class ColorPickerUI : Window
    {
        public ColorPickerUI()
        {
            InitializeComponent();
        }

        private void _colorCanvas_SelectedColorChanged
        (object sender, RoutedPropertyChangedEventArgs<System.Windows.Media.Color> e)
        {
            _colorPicker.SelectedColor = _colorCanvas.SelectedColor;
        }
        private void _colorPicker_SelectedColorChanged
        (object sender, RoutedPropertyChangedEventArgs<Color> e)
        {
            _colorCanvas.SelectedColor = _colorPicker.SelectedColor;
        }

        private void btnCopy_Click(object sender, RoutedEventArgs e)
        {
            Clipboard.SetText(_colorCanvas.HexadecimalString);
        }
    }
}

输出

摘要

在本文中,我试图解释如何通过 Visual Studio 集成颜色选择器来创建 Visual Studio Package。

我在我所有的文章中投入了时间和精力。请不要忘记投下您的选票、建议和反馈,以提高本文及后续文章的质量。

历史

  • 2014 年 6 月 1 日:初始版本
© . All rights reserved.