The ribbon controls such as “Object Color Gallery” and “Layer List Combo Box” ribbon
controls are useful for accepting color and layer input and can be placed in ribbon tabs. These controls are data-bound and any user input using these controls also ensures that the entity property gets modified. If you wish to accept color / layer input without such automatic property update to the entity, then you will need your own implementation of the controls.
Implementing such a control is a programming task involving WPF and with very little use of AutoCAD API. Iam sharing this project to provide a starting point for your own implementation which you can improvise based on your requirements and hopefully saves you some time.
Here is some relevant portions of the code from the sample project that you can download.
1) ViewModel class and collection classes for the Color control :
// Class that represents the collection of AcadColor
public class AcadColors : ObservableCollection
{
public AcadColors()
: base()
{
// List of colors to show in the combo box
// along with their R,G,B values
Add(new AcadColor("ByLayer", 255, 255, 255));
Add(new AcadColor("ByBlock", 255, 255, 255));
Add(new AcadColor("Red", 255, 0, 0));
Add(new AcadColor("Yellow", 255, 255, 0));
Add(new AcadColor("Green", 0, 255, 0));
Add(new AcadColor("Cyan", 0, 255, 255));
Add(new AcadColor("Blue", 0, 0, 255));
Add(new AcadColor("Magenta", 255, 0, 255));
Add(new AcadColor("White", 255, 255, 255));
Add(new AcadColor("Select Colors...", 255, 255, 255));
}
// To check if a color with a given name
// exists in this collection
public bool Contains(String name)
{
for(int i = 0; i < Count; i++)
{
if(this[i].Name.Equals(name))
return true;
}
return false;
}
}
// Class that represents a single color
public class AcadColor
{
// Color Name
public String Name
{
get;
set;
}
// Brush to bind the label that displays the color
public System.Windows.Media.SolidColorBrush ColorBrush
{
get
{
SolidColorBrush brush
= new SolidColorBrush(
Color.FromRgb(Red, Green, Blue));
return brush;
}
}
// Red byte
public byte Red
{
get;
set;
}
// Green byte
public byte Green
{
get;
set;
}
// Blue byte
public byte Blue
{
get;
set;
}
// The Color combo displays a "Select color..." option
// In that case, we do not want to show the color label
public String IsVisible
{
get
{
if(Name.Contains("Select"))
return "Collapsed";
return "Visible";
}
}
public AcadColor(String name, byte R, byte G, byte B)
{
Name = name;
Red = R;
Green = G;
Blue = B;
}
public AcadColor()
{
Name = String.Empty;
Red = 255;
Green = 255;
Blue = 255;
}
}
// View Model for the Color Combo box to bind to
public class ColorViewModel : INotifyPropertyChanged
{
// collection of colors that we will display
AcadColors _myAcadColors = new AcadColors();
// Flag to know if we are displaying the color selection dialog
bool _showingColorDlg = false;
public ColorViewModel()
{
}
// Bound to the combo box source
public AcadColors MyAcadColors
{
get
{
return _myAcadColors;
}
}
// Default value to show
private string _colorString = "Red";
// Bound to the current selection in the combo
public string ColorString
{
get
{
return _colorString;
}
set
{
if (_colorString != value)
{
String colorName = value;
//The Color combo displays a "Select color..."
// option. If that is the option chosen,
// show the color pick dialog
if (! _showingColorDlg && value.Contains("Select"))
{// Show the color pick dialog
_showingColorDlg = true;
colorName = ShowColorDlg();
}
_showingColorDlg = false;
_colorString = colorName;
NotifyPropertyChanged("ColorString");
}
}
}
#region INotifyPropertyChanged Members
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
// Displays the AutoCAD color pick dialog
// Method returns the name to be displayed in the combo box
public String ShowColorDlg()
{
Document doc
= Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Autodesk.AutoCAD.Windows.ColorDialog dlg
= new Autodesk.AutoCAD.Windows.ColorDialog();
if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK)
{
return String.Empty;
}
Autodesk.AutoCAD.Colors.Color clr = dlg.Color;
if (! clr.IsByAci)
{
if (clr.IsByLayer)
{
return "ByLayer";
}
else if (clr.IsByBlock)
{
return "ByBlock";
}
else
{
String colorName
= String.Format("{0},{1},{2}",
clr.Red, clr.Green, clr.Blue);
if(_myAcadColors.Contains(colorName) == false)
_myAcadColors.Insert(
_myAcadColors.Count - 1,
new AcadColor(
colorName,
clr.Red,
clr.Green,
clr.Blue
));
return colorName;
}
}
else
{
// Get the AutoCAD color index
short colIndex = clr.ColorIndex;
System.Byte byt = System.Convert.ToByte(colIndex);
int rgb
= Autodesk.AutoCAD.Colors.EntityColor.LookUpRgb(byt);
long b = (rgb & 0xffL);
long g = (rgb & 0xff00L) >> 8;
long r = rgb >> 16;
String colorName = String.Format("Color {0}", colIndex);
if (_myAcadColors.Contains(colorName) == false)
_myAcadColors.Insert(
_myAcadColors.Count - 1,
new AcadColor(
colorName,
(byte)r, (byte)g, (byte)b));
return colorName;
}
}
}
2) ViewModel class and collection classes for the Layer control :
// Class that represents the collection of AcadLayer
public class AcadLayers : ObservableCollection
{
public AcadLayers()
: base()
{
// Gather the list of layers to show in the combo box
// along with their color R,G,B values and layer state information
Document doc
= Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
using (Transaction tr
= db.TransactionManager.StartTransaction())
{
LayerTable lt
= tr.GetObject (
db.LayerTableId,
OpenMode.ForRead
) as LayerTable;
foreach(ObjectId ltrId in lt)
{
LayerTableRecord ltr
= tr.GetObject(
ltrId,
OpenMode.ForRead
) as LayerTableRecord;
Autodesk.AutoCAD.Colors.Color clr = ltr.Color;
if (!clr.IsByAci)
{
if (clr.IsByLayer)
{
Add(new AcadLayer( ltr.Name,
(byte)255,
(byte)255,
(byte)255,
!ltr.IsOff,
ltr.IsFrozen,
ltr.IsLocked));
}
else if (clr.IsByBlock)
{
Add(new AcadLayer( ltr.Name,
(byte)255,
(byte)255,
(byte)255,
!ltr.IsOff,
ltr.IsFrozen,
ltr.IsLocked));
}
else
{
Add(new AcadLayer( ltr.Name,
clr.Red,
clr.Green,
clr.Blue,
!ltr.IsOff,
ltr.IsFrozen,
ltr.IsLocked));
}
}
else
{
// Get the AutoCAD color index
short colIndex = clr.ColorIndex;
System.Byte byt = System.Convert.ToByte(colIndex);
int rgb
= Autodesk.AutoCAD.Colors.EntityColor.LookUpRgb(byt);
long b = (rgb & 0xffL);
long g = (rgb & 0xff00L) >> 8;
long r = rgb >> 16;
if (colIndex == 7)
{
if (r
3) Layout of the controls in Xaml :
<ComboBox DataContext="{Binding ColorDataContext}"
Name="MyColorCombo"
Margin="2" Height="30" Width="250"
ItemsSource="{Binding MyAcadColors}"
SelectedValuePath="Name"
SelectedValue="{Binding ColorString}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="2">
<Label Visibility="{Binding IsVisible}"
Background="{Binding ColorBrush}"
Width="15" Height="15"
BorderBrush="Black" BorderThickness="1"/>
<TextBlock Visibility="{Binding IsVisible}"
Text=" " Width="3"/>
<TextBlock Text="{Binding Name}" Width="100"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox Name="MyLayerCombo"
DataContext="{Binding LayerDataContext}"
Margin="2" Height="30" Width="250"
ItemsSource="{Binding MyAcadLayers}"
SelectedValuePath="Name"
SelectedValue="{Binding LayerString}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="2">
<Image Tag="{Binding LayerName}"
Visibility="{Binding IsOn}"
Source="{StaticResource LayerOnImage}"/>
<Image Tag="{Binding LayerName}"
Visibility="{Binding IsOff}"
Source="{StaticResource LayerOffImage}"/>
<Image Tag="{Binding LayerName}"
Visibility="{Binding IsFrozen}"
Source="{StaticResource LayerFreezeImage}"/>
<Image Tag="{Binding LayerName}"
Visibility="{Binding IsThawed}"
Source="{StaticResource LayerThawImage}"/>
<Image Tag="{Binding LayerName}"
Visibility="{Binding IsLocked}"
Source="{StaticResource LayerLockImage}"/>
<Image Tag="{Binding LayerName}"
Visibility="{Binding IsUnLocked}"
Source="{StaticResource LayerUnlockImage}"/>
<Label Visibility="{Binding IsVisible}"
Background="{Binding LayerColorBrush}"
Width="15" Height="15"
BorderBrush="Black"
BorderThickness="1"/>
<TextBlock Visibility="{Binding IsVisible}"
Text=" " Width="3"/>
<TextBlock Text="{Binding LayerName}"
Width="100"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
To try the attached project, build the sample project, netload the dll and run the “Test” command. This command should display a palette with the color and layer controls. The controls display the information based on the active document and if you wish to reload this information, click on the reload button.
Here is the screenshot of the output.


Leave a Reply