I have a shape object drawn as a 'group' such that the two sub-shapes are direct children of the group. All the shapes in the group have distinguishing colors.
I wish to know what is that property which can help me to get the color of the shape objects (Red, Green, White).
I know that shape has style property (Shape.Style) but that does not gives me the color value.
Application visApp = new Application();
Document visDoc = visApp.Documents.Open(VisiofilePath);
var shp = visApp.ActivePage.Shapes.ItemFromID[1];
string shapeColor = string.Empty;
foreach (Visio.Shape s in shp.Shapes)
{
if(s.Text == "Child Object 1")
{
//shapeColor =
}
if(s.Text == "Child Object 2")
{
//shapeColor =
}
}
Any help will be much appreciated.
Getting hold of the fill color is not impacted by whether the shape is part of a group or not. Once you've got a reference to the right shape then you can look at the respective cells.
Visio has two main methods of setting the fill color - Pattern fill and Gradient fill. The latter is from 2013 onwards.
For Pattern fill, you're looking at three cells: FillForegnd
, FillBkgnd
and FillPattern
. Most shapes start off with a solid fill (FillPattern
1) and this means that only the FillForegnd
is used. For other pattern types you're dealing with both FillForegnd
and FillBkgnd
.
For Gradient fill the FillGradientEnabled
cell is set to 1 and this results in the Fill Gradient Stops
section taking precedents.
In the background, Visio maintains a Document.Colors
collection. Some built-in colors can be accessed by index: 0 = black, 1 = white, 2 = red, 3 = green etc all the way up to 23. Any additional custom colors used are added to the collection and are also given an index. This means that, given an index, you can look up the color instance in the Colors collection.
Following is some code to demo how to access the various types of coloring. Given these four shapes:
The first 3 shapes use Pattern fill, while the last uses Gradient fill.
3
), 2
) and so uses both Foreground and Background cells... you could use the following code to read the colors at work (note this is using LINQPad as the output window makes it clearer to see what's going on:
void Main()
{
var vApp = MyExtensions.GetRunningVisio();
for (int i = 1; i <= 4; i++)
{
var shp = vApp.ActivePage.Shapes.ItemFromID[i];
var colorInfos = new List<ColorInfo>();
colorInfos.Add(new ColorInfo(shp.CellsU["FillForegnd"]));
colorInfos.Add(new ColorInfo(shp.CellsU["FillBkgnd"]));
new
{
shp.NameID,
FillPattern = shp.CellsU["FillPattern"].ResultIU,
FillGradientEnabled = Convert.ToBoolean(shp.CellsU["FillGradientEnabled"].ResultIU),
PatternColors = colorInfos,
GradientColors = FillGradientColors(shp) ?? "Default (10 stops all white)"
}.Dump();
}
}
private dynamic FillGradientColors(Visio.Shape shp)
{
List<string> rgbs = null;
var iSect = (short)Visio.VisSectionIndices.visSectionFillGradientStops;
for (int i = 0; i < shp.RowCount[iSect]; i++)
{
var targetCell = shp.CellsSRC[iSect, (short)i, (short)Visio.VisCellIndices.visGradientStopColor];
if (targetCell.IsInherited == 0)
{
if (rgbs is null)
{
rgbs = new List<string>();
}
rgbs.Add(ColorInfo.RgbString(targetCell));
}
}
return rgbs;
}
public class ColorInfo
{
private Visio.Cell _vCell;
public ColorInfo(Visio.Cell vCell)
{
_vCell = vCell;
RGB = RgbString(_vCell);
}
public string Name => _vCell.Name;
public string RGB { get; set; }
public string FormulaU => _vCell.FormulaU;
public static string RgbString(Visio.Cell cell)
{
var colorIdx = cell.Result[(short)Visio.VisUnitCodes.visUnitsColor];
var c = cell.Document.Colors.Item16[(short)colorIdx];
return $"RGB({c.Red},{c.Green},{c.Blue})";
}
}
... this produces the following output: