Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Integrated Color Picker for Visual Studio IDE - VSPackage (AddIn)

5.00/5 (14 votes)
2 Jul 2014CPOL6 min read 50.1K   1.2K  
Color Picker tool for Visual Studio IDE, VSPackage walkthrough

Image 1

Introduction

Integrated Color Picker for Visual Studio will be very useful to you, if you are working as a Web Developer or UI designer, who mainly uses Visual Studio for their day to day assignments. In this article, I'm going to give you a walkthrough on the Color Picker AddIn (or Plugin).

If you would like to get the latest version of Color Picker AddIn, then click here.

Integrated Color Picker for Visual Studio

Background

Sometimes, I used to work in UI designing like changing color or alignment using CSS and or HTML markups and I found it difficult to get a color picker directly from the IDE for my purpose. So I thought of writing my own color picker plugin for Visual Studio. I will be sharing the initial code here so that you can also play with it.

Using the Code

I have used some components from Extended WPF Toolkit for this Color Picker tool. Before you start on this, it would be better to have a look at the article, 'Using Color Canvas and Color Picker from Extended WPF Toolkit', so that you will get to know the implementation of Color Canvas, Color Picker from Extended WPF Toolkit.

There are many ways to extend Visual Studio. Three common ones are: automation, VSPackage extensions, and Managed Extensibility Framework (MEF) extensions. Visual Studio add-ins are deprecated in Visual Studio 2013. You should upgrade your add-ins to VSPackage extensions.

I will be using Visual Studio Package (VSPackage) for creating this AddIn. You might be interested in Web Search that is created using Visual Studio Add-In project template.

To start developing Visual Studio extensions, you first need to download and install the Visual Studio SDK at the Visual Studio 2013 SDK download website. It is compatible with the Visual Studio 2013 Professional, Premium, or Ultimate editions. I'm using Visual Studio 2013. If you are using a different version, then make sure you have the right version of Visual Studio SDK installed.

New Project

Integrated Color Picker for Visual Studio - Visual Studio Package

Here, I have selected New Project -> Other Project Types -> Extensibility, then after selecting Visual Studio Package project template, I named the project name as Color Picker. Now click OK to continue.

Note: If you don't see the Visual Studio Package under Other Project Types, then you must install the Visual Studio SDK. For more information about the Visual Studio SDK, see Extending Visual Studio Overview. To find out how to download the Visual Studio SDK, see Visual Studio Extensibility Developer Center on the MSDN Web site.

Use the following options in Visual Studio Package wizard.

Image 4

Page 1 of 7 - Select a Programming Language

Image 5

Select your language as Visual C# and generate a new key file to sign the assembly.

Page 2 of 7 - Basic VSPackage Information

Image 6

I have entered the Basic VSPackage Information as shown in the above picture.

Page 3 of 7 - Select VSPackage Options

Image 7

Select Menu Command. By default, this will add a Menu Item under Tools menu.

Page 4 of 7 - Command Options

Image 8

Change the command name to "Color Picker".

Page 7 of 7 - Select Test Project Options

Image 9

You should select Integration Test Project and Unit Test Project, but for now, deselect these. :)

Click Finish.

Image 10

Visual Studio will now create the base Project for you. Now we have the Solution file ready, the solution file screen-shot is given below:

Image 11

Let us run (F5) this application to see what we have got now.

Once we run the application, we can check the AddIn functionality in Visual Studio Experimental Instance. If you click on the Tools menu in experimental instance, then we can see the Command "Color Picker" as below:

Image 12

Click on the "Color Picker" menu to see the default code base in action.

Image 13

Wondering how we got the Color Picker menu under Tools menu. In ColorPicker.vsct file, we have mentioned the Menu Group parent as Tool Menu.

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

and the Menu Item name and Icon are mentioned in <Button>.

XAML
<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>

The Icon is specified in <Bitmaps><Bitmap> and GuidSymbols are defined under <Symbols>. Use source.extension.vsixmanifest file to change the Icon and Preview Image which will be displayed in Extension Manager window. This file can be used to change the target Visual Studio versions and frameworks, etc.

ColorPickerPackage.cs is used to add the menu item and its functionalities. The below code from ColorPickerPackage.cs is used to add the Menu Item to the IDE Menu.

C#
/////////////////////////////////////////////////////////////////////////////
// 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

The MenuItemCallback will be called when you click on the Color Picker menu. Below, I have given the default implementation of MenuItemCallback this in turn shows the message box currently.

C#
/// <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));
}

Now let's talk about the actual color picker implementation. As we are utilizing components from Extended WPF Toolkit, we need to refer to the toolkit binaries in our application.

I'm going to add reference of "Xceed.Wpf.Toolkit.dll" from "Extended WPF Toolkit Binaries". Read article 'Using Color Canvas and Color Picker from Extended WPF Toolkit' for detailed steps of adding reference.

Once we add the reference to "Xceed.Wpf.Toolkit.dll", we need to add a WPF window that will be used to host the color picker functionalities.

Image 14

I have named the WPF Window name as ColorPickerUI.xaml.

Image 15

At first, I'm going to add an xmlns to the recently added window that will enable us to use controls from Extended WPF Toolkit.

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:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        Title="ColorPickerUI" Height="300" Width="300">
    <Grid>
        
    </Grid>
</Window>

Then, after I have added three rows for the <Grid>, these rows will hold the actual controls.

XAML
<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>

Now I have added Row 1 (Color Canvas):

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

Row 2 is given as below (Color Picker):

XAML
<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>

Row 3 is given as below (Copy Color Code):

XAML
<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>

To make the Color Canvas and Color picker show the same color, I have added SelectedColorChanged method for both the controls as below:

XAML
SelectedColorChanged="_colorCanvas_SelectedColorChanged"

SelectedColorChanged="_colorPicker_SelectedColorChanged"

Event definition is added in xaml.cs as below:

C#
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;
}

The above codes will set the selected color of both controls same when any color change happens. To copy the Color Code using "Copy" button, I have added the click event for Copy button as below:

C#
Click="btnCopy_Click"

and the definition added as below in xaml.cs file:

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

Make sure you have referenced System.xaml in this project.

The full source code is given below. The full working source code is attached with this article.

ColorPickerUI.xaml

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

C#
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);
        }
    }
}

Output

Image 16

Summary

In this article, I have tried to explain how to create a Visual Studio Package with the help of Integrated Color Picker for Visual Studio.

I have put my time and effort in all of my articles. Please don't forget to mark your votes, suggestions and feedback to improve the quality of this and upcoming articles.

History

  • 1st June, 2014: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)