使用Visio 2003 Drawing Control开发应用(3)
单靠这些对象的一些属性和方法,一般来说是很难处理一些细节上的东西。比如说:要动态的为一个shape添加连接点,根本是找不到
方法可以利用的。这个时候,操作ShapeSheet就是关键了。
不知道大家用过ShapeSheet没有,在visio下,选中某个shape,然后在点窗口->显示ShapeSheet,就可以看到好多关于这个shape
的属性,改变shape的一些表现时,这些值会作相应变化。(visio里面的shapesheet没有显示出所有的属性)
但是那么多的格子,我们应该操纵哪个呢?而且可能会有关联的。这个好办,祭出一招大旗,就是宏。当我们想完成某项功能时,就在
Visio下模拟做一下,同时录制宏,然后看VBA代码,就知道visio是怎么操作了,改一下就可以了用到C#了。
比如下面的代码就是我动态给一个shape添加连接点
short count = shape.get_RowCount((short)VisSectionIndices.visSectionConnectionPts);
short rowIndex = shape.AddRow((short)VisSectionIndices.visSectionConnectionPts, (short)VisRowIndices.visRowLast, (short)
VisRowTags.visTagCnnctPt);
Row rowAdded = shape.get_Section((short)VisSectionIndices.visSectionConnectionPts)[rowIndex];
rowAdded.get_CellU(VisCellIndices.visCnnctX).FormulaU = "Width*" + (sequence * 0.1).ToString();
rowAdded.get_CellU(VisCellIndices.visCnnctY).FormulaU = "Height*0";
rowAdded.get_CellU(VisCellIndices.visCnnctDirX).FormulaU = "0";
rowAdded.get_CellU(VisCellIndices.visCnnctDirY).FormulaU = "1";
rowAdded.get_CellU(VisCellIndices.visCnnctType).FormulaU = ((short)VisCellVals.visCnnctTypeInward).ToString();
double x = shape.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowXFormOut, (short)
VisCellIndices.visXFormWidth).ResultIU;
double y = shape.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowXFormOut, (short)
VisCellIndices.visXFormHeight).ResultIU;
x = x * (sequence * 0.1);
Shape rect = shape.DrawRectangle(x, -0.1, x + (0.1 * content.Length), -0.2);
rect.TextStyle = "Text Only";
rect.LineStyle = "Text Only";
rect.FillStyle = "Text Only";
rect.Characters.Begin = 1;
rect.Characters.End = 1;
rect.Text = content;
rect.get_CellsSRC((short)VisSectionIndices.visSectionCharacter, 0, (short)VisCellIndices.visCharacterSize).FormulaU = "9pt";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowMisc, (short)
VisCellIndices.visGlueType).FormulaU = "8";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowMisc, (short)
VisCellIndices.visNoObjHandles).FormulaU = "TRUE";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowMisc, (short)
VisCellIndices.visNoCtlHandles).FormulaU = "TRUE";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowMisc, (short)
VisCellIndices.visNoAlignBox).FormulaU = "TRUE";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockWidth).FormulaU = "1";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockHeight).FormulaU = "1";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockMoveX).FormulaU = "1";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockMoveY).FormulaU = "1";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockAspect).FormulaU = "1";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockDelete).FormulaU = "1";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockBegin).FormulaU = "1";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockEnd).FormulaU = "1";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockRotate).FormulaU = "1";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockTextEdit).FormulaU = "1";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockFormat).FormulaU = "1";
rect.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)
VisCellIndices.visLockSelect).FormulaU = "1";
一开始就是AddRow来增加connnection points的个数,然后设置连接点的位置
后来的代码就是增加一个文本框来写入一些描述信息,然后设置这个文本框的一些保护属性。
一定要看看visio怎么设置的,大家看到,里面有的保护属性用1,有的用TRUE。很乱的。
出了这些shape的属性,有时候想关联某个shape和一些数据,但是并不希望显示出来。这个visio的shape提供了三个属性供使用,就
是我前面提到的Data1, Data2, Data3。我们可以在这里放一些字符串(当然可以放xml了)。
还有一个可以放置自定义xml的地方,就是visio提供的soluctionxml,在这个标签下的任何xml都可以随着visio图形保留。可惜,这个
solutionxml不是面向shape的,是对page而言的(?)。
像我开发的程序,需要一些自定义的模具,而且里面的Master会动态变化,这样,就需要操纵visio xml了。
第一步当然要熟悉visio xml schema了。msdn上讲的很详细。
具体看一下我的实现,我先用visio做好了一些master,将master那部分xml单独拿出来,然后动态插到预先设计好的空白stencil文件
中
XmlDocument xmlDomComponent = new XmlDocument();
xmlDomComponent.Load(stencilPath + @"\10.xml"); // 加载预先定义好的Master的文件
XmlNode nodeMaster = xmlDomComponent.GetElementsByTagName("Master").Item(0);
if(nodeMaster != null)
{
nodeMaster.Attributes["ID"].InnerText = m.ToString(); // 设置该Master的ID
m++;
nodeMaster.Attributes["Name"].InnerText = resourceChinese; // 设置名字
nodeMaster.Attributes["NameU"].InnerText = resourceChinese;
nodeMaster.Attributes["Prompt"].InnerText = resourceName + " 属于地区" + cityCode; // 设置提示
Guid newUniqueID = Guid.NewGuid();
nodeMaster.Attributes["UniqueID"].InnerText = "{" + newUniqueID.ToString().ToUpper() + "}"; // 生成新的GUID
Guid newBaseID = Guid.NewGuid();
nodeMaster.Attributes["BaseID"].InnerText = "{" + newBaseID.ToString().ToUpper() + "}"; // 生成新的Base GUID
XmlNodeList lstShapes = xmlDomComponent.GetElementsByTagName("Shape");
for(int j = 0; j < lstShapes.Count; j++)
{
XmlAttribute attrName = lstShapes.Item(j).Attributes["NameU"];
if(attrName != null)
{
if(lstShapes.Item(j).Attributes["NameU"].InnerText == "Rounded rectangle") // 设置应该显示出来的文
字
{
lstShapes.Item(j).InnerXml += "<Text>" + resourceChinese + "</Text>";
break;
}
}
}
mastersComInnerXml.Append(xmlDomComponent.GetElementsByTagName("Test").Item(0).InnerXml); // 添加Master到
Stencil里面
}
xmlDomComComponent.GetElementsByTagName("Masters").Item(0).InnerXml = mastersComInnerXml.ToString();
//将生成的模具文件写到目录中去
XmlTextWriter writer = new XmlTextWriter(stencilPath + "\\" + randomDirectory + @"\" + componentType + ".vsx", null);
writer.Formatting = Formatting.Indented;
xmlDomComComponent.WriteContentTo(writer);
writer.Close();
File.SetAttributes(stencilPath + "\\" + randomDirectory + @"\" + componentType + ".vsx", FileAttributes.ReadOnly);
这样,这个stencil生成好了之后,就可以在程序用调用OpenEx方法打开了。