日期:2009-07-26  浏览次数:20373 次


  第 5 章 用户互操作:提示和选择
  背景
  提示通常包含一个描述性信息,伴随一个停止以让用户理解所给的信息并输入数据。数据可以通过多种方式被输入,如通过命令行、对话框或AutoCAD编辑窗口。给出的提示要遵循一定的格式,格式要与一般的AutoCAD提示相一致,这一点是非常重要的。例如,关键字要用“/”号分隔并放在方括号“[]”中,缺省值要放在“<>”内。对于一个AutoCAD用户来说,坚持统一的格式将会减少信息理解错误的产生。
  当用户在AutoCAD命令行中选择一个实体时,实体是使用选择机制被选择的。这种机制包括一个提示,用来让用户知道选择什么并怎样选择(如,窗口或单一实体),然后是一个停顿。
  试一下诸如PINE这种命令来看一下提示的显示,PEDIT来看一下使用单一实体或多线来进行选择。
  练习
  Prompts:
  提示:
  在本章中,我们将提示输入雇员名字、职位、薪水和部门来创建一个雇员块索引对象。如果输入的部门不存在,我们将提示输入部门经理的名字来创建一个新的部门。在我们继续之前,让我们试着重用以前的代码。
  为了进行选择,我们将提示用户在一个窗口中进行选择或选择一个实体,而我们只显示选择集中的雇员对象。
  在前面的章节中,我们创建了一个名叫“Earnest Shackleton”的雇员,名字被存储为“EmployeeBlock”块定义(块表记录)中的MText。如果我们多次插入这个块,那么我们看到的都是同一个雇员的名字。我们怎样才能自定义这个块以使每次插入这个块的时候显示不同雇员的名字?这就要使用块属性的功能了。属性是存储在每一个块索引实例中的文本,并被作为实例的一部分来被显示。属性从存储在块表记录中的属性定义中继承相关的属性。
  属性:
  让我们来把MText实体类型改变为属性定义。在CreateEmployeeDefinition()函数中,把下面的代码替换
  
  //文本:
  MText text = new MText();
  text.Contents = "Earnest Shackleton";
  text.Location = center;
  
  为
  
  //属性定义
  AttributeDefinition text = new AttributeDefinition(center, "NoName", "Name:", "Enter Name", db.Textstyle);
  text.ColorIndex = 2;
  
  试着使用TEST命令来测试一下CreateEmployeeDefinition()函数:
   [CommandMethod("Test")]
   public void Test()
   {
   CreateEmployeeDefinition();
   }
  
  你现在应该可以使用INSERT命令来插入EmployeeBlock块并对每一个实例确定一个雇员名。
  当你插入Employee块时,请注意一下块插入的位置。它是正好被放置在所选点还是有些偏移?试试怎样修复它。(提示:检查块定义中的圆心)
  修改CreateEmployee ()以重用
  
  1)让我们来修改CreateEmployee()函数,以让它可以接收名字、薪水、部门和职位并返回创建的雇员块索引的ObjectId。函数的形式如下(你可以改变参数顺序)
  public ObjectId CreateEmployee(string name, string division, double salary, Point3d pos)
  
  2) 移除上面函数中的CommandMethod属性”CREATE”,这样它就不再是用来创建雇员的命令。
  3) 修改函数的代码,这样就可以正确地设置块索引的名字、职位、部门和薪水和它的扩展字典。
  · 替换
  
  BlockReference br = new BlockReference(new Point3d(10, 10, 0), CreateEmployeeDefinition());
  
  为
  
  BlockReference br = new BlockReference(pos, CreateEmployeeDefinition());
  
  · 替换
  
   xRec.Data = new ResultBuffer(
   new TypedValue((int)DxfCode.Text, "Earnest Shackleton"),
   new TypedValue((int)DxfCode.Real, 72000),
   new TypedValue((int)DxfCode.Text, "Sales"));
  
  为
  
   xRec.Data = new ResultBuffer(
   new TypedValue((int)DxfCode.Text, name),
   new TypedValue((int)DxfCode.Real, salary),
   new TypedValue((int)DxfCode.Text, division));
  
  4) 因为我们把雇员的名字从MText替换成块的属性定义,因此我们要创建一个相应的属性索引来显示雇员的名字。属性索引将使用属性定义的属性。
  · 替换:
  
   btr.AppendEntity(br); //加入索引到模型空间
   trans.AddNewlyCreatedDBObject(br, true); //让事务处理知道
  
  为
  
   AttributeReference attRef = new AttributeReference();
   //遍历雇员块来查找属性定义
   BlockTableRecord empBtr = (BlockTableRecord)trans.GetObject(bt["EmployeeBlock"], OpenMode.ForRead);
   foreach (ObjectId id in empBtr)
   {
   Entity ent = (Entity)trans.GetObject(id, OpenMode.ForRead, false);
   //打开当前的对象!
   if (ent is AttributeDefinition)
   {
   //设置属性为属性索引中的属性定义
   AttributeDefinition attDef = ((AttributeDefinition)(ent));
   attRef.SetPropertiesFrom(attDef);
   attRef.Position = new Poi