国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Autodesk官方最新的.NET教程(五)(C#版)

2019-11-18 19:17:59
字體:
來源:轉載
供稿:網友
  第 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 Point3d(attDef.Position.X + br.Position.X, attDef.Position.Y + br.Position.Y, attDef.Position.Z + br.Position.Z);
   attRef.Height = attDef.Height;
   attRef.Rotation = attDef.Rotation;
   attRef.Tag = attDef.Tag;
   attRef.TextString = name;
   }
   }
   //把索引加入模型空間
   btr.AppendEntity(br);
   //把屬性索引加入到塊索引
   br.AttributeCollection.AppendAttribute(attRef);
   //讓事務處理知道
   trans.AddNewlyCreatedDBObject(attRef, true);
   trans.AddNewlyCreatedDBObject(br, true);
  
  
  研究一下上面的代碼,看看是怎樣把屬性定義中除顯示用的文本字符串外的屬性復制到屬性索引的。屬性被加入到塊索引的屬性集合中。這就是你怎樣來為每一個實例自定義雇員名字。
  5)不要忘記返回雇員塊索引的ObjectId,但要在提交事務處理之后才能返回:
  trans.Commit();
  return br.ObjectId;
  
  6) 測試CreateEmployee。
  加入一個Test命令來測試CreateEmployee:
  
   [CommandMethod("Test")]
   public void Test()
   {
   CreateEmployee("Earnest Shackleton", "Sales", 10000, new Point3d(10, 10, 0));
   }
  
  
  修改CreateDivision()以重用:
  讓我們來修改CreateDivision ()函數,以讓它可以接收部門名字、經理名字并返回創建的部門經理擴展記錄的ObjectId。如果部門經理已經存在,則不改變經理的名字。
  1) 如果你先前在CreateEmployeeDefinition()中調用了CreateDivision(),請把它注釋掉,因為我們在這里不需要創建一個部門
  2)   改變CreateDivision()的形式讓它接收部門和經理的名字并返回一個ObjectId。
  public ObjectId CreateDivision(string division, string manager)
  3) 修改上面函數的代碼創建部門的名字和經理:
  · 替換:
  
  divDict = (DBDictionary)trans.GetObject(acmeDict.GetAt("Sales"), OpenMode.ForWrite);
  
  為:
  
  divDict = (DBDictionary)trans.GetObject(acmeDict.GetAt(division), OpenMode.ForWrite);
  
  · 替換:
  
  acmeDict.SetAt("Sales", divDict);
  
  為:
  
  acmeDict.SetAt(division, divDict);
  
  · 替換:
  
  mgrXRec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, "Randolph P. Brokwell"));
  
  為:
  
  mgrXRec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, manager));
  
  
  不要忘了返回部門經理這個擴展記錄的ObjectId,但要在提交事務處理后才返回。
  trans.Commit();
  //返回部門經理這個擴展記錄的ObjectId
  return mgrXRec.ObjectId;
  
  現在把在中CreateEmployeeDefinition調用的CreateDivision函數給注釋掉。
  4) 現在通過使用TEST命令來測試調用CreateDivision函數。使用ArxDbg工具來檢查條目是否已被加入到“ACME_DIVISION”下的命名對象字典。
  CreateDivision("Sales", "Randolph P. Brokwell")
  
  使用CREATE命令來創建雇員:
  
  我們將加入一個名為CREATE的新命令,此命令用來提示輸入雇員的詳細資料來創建雇員塊索引。讓我們來看一下這個命令是怎樣使用的。
  1) 讓我們加入一個名為CREATE的新命令,并聲明幾個常用的變量和一個try-finally塊。
  
  [CommandMethod("CREATE")]
  public void CreateEmployee()
  {
   Database db = HostapplicationServices.WorkingDatabase;
   Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
   Transaction trans = db.TransactionManager.StartTransaction();
   try
   {
   trans.Commit();
   }
   finally
   {
   trans.Dispose();
   }
  }
  
  
  2) 讓我們來為雇員定義可以用作為提示缺省值的常數。注意,布爾值gotPosition是用來判斷用戶是否已輸入職位。
  . 雇員名 - 類型 :String -缺省值 “Earnest Shackleton”
  . 雇員所在部門名   - 類型:String     -缺省值“Sales”
  . 薪水 -類型:Double (non-negative and not zero) -缺省值10000
  . 職位 -類型:Point3d -缺省值(0,0,0)
  
  把這些常數加入到try語句后面:
  string empName = "Earnest Shackleton";
  string divName = "Sales";
  double salary = new double();
  salary = 10000;
  Point3d position = new Point3d(0, 0, 0);
  bool gotPosition = new bool();
  //布爾值用來判斷用戶是否已輸入職位
  gotPosition = false;
  
  3) 現在讓我們提示用戶輸入值。我們先使用PromptXXXOptions類來初始化要顯示的提示字符串。
  //提示輸入每個雇員的詳細資料
  PromptStringOptions prName = new PromptStringOptions("Enter Employee Name <" + empName + ">");
  PromptStringOptions prDiv = new PromptStringOptions("Enter Employee Division <" + divName + ">");
  PromptDoubleOptions prSal = new PromptDoubleOptions("Enter Employee Salary <" + salary + ">");
  PromptPointOptions prPos = new PromptPointOptions("Enter Employee Position or");
  
  注意,提示字符串用尖括號來顯示變量的值。這是AutoCAD用來提示用戶這個值為缺省值。
  4) 當提示用戶輸入職位時,我們也提供了一個關鍵字列表選項,如名字、部門和薪水。如果用戶想要在選擇一個點的時候改變為其它值,他可以選擇那個關鍵字。
  一個命令提示的例子如下:
  Command: CREATE
  Enter Employee Position or [Name/Division/Salary]:
  
  要創建一個雇員,用戶會選擇一個點而其它的值被設置為缺省值。如果用戶要改變其它的值,如名字,他可以輸入”N”或全名”Name”,然后輸入名字:
  Command: CREATE
  Enter Employee Position or [Name/Division/Salary]:N
  Enter Employee Name <Earnest Shackleton>:
  
  如果用戶想要再次選擇缺省的名字,他可以按回車鍵。
  讓我們創建用于職位提示的關鍵字列表:
  
  //加入用于職位提示的關鍵字
  prPos.KeyWords.Add("Name");
  prPos.Keywords.Add("Division");
  prPos.Keywords.Add("Salary");
  //設置提示的限制條件
  prPos.AllowNone = false; //不允許沒有值
  
  
  5) 現在讓我們聲明PromptXXXResult變量來獲取提示的結果:
  //prompt results
  PromptResult prNameRes;
  PromptResult prDivRes;
  PromptDoubleResult prSalRes;
  PromptPointResult prPosRes;
  
  6) 直到用戶成功輸入一個點后,循環才結束。如果輸入錯誤的話,我們會提示用戶并退出函數:
  判斷用戶是否輸入了關鍵字,我們通過檢查promptresult的狀態來進行:
  //循環用來獲取雇員的詳細資料。當職位被輸入后,循環終止。
  while (!gotPosition)
  {
   //提示輸入職位
   prPosRes = ed.GetPoint(prPos);
   //取得一個點
   if (prPosRes.Status == PromptStatus.OK)
   {
   gotPosition = true;
   position = prPosRes.Value;
   }
   else if (prPosRes.Status == PromptStatus.Keyword) //獲取一個關鍵字
   {
   //輸入了Name關鍵字
   if (prPosRes.StringResult == "Name")
   {
   //獲取雇員名字
   prName.AllowSpaces = true;
   prNameRes = ed.GetString(prName);
   if (prNameRes.Status != PromptStatus.OK)
   {
   return;
   }
   //如果獲取雇員名字成功
   if (prNameRes.StringResult != "")
   {
   empName = prNameRes.StringResult;
   }
   }
   }
   else
   {
   // 獲取職位時發生錯誤
   ed.WriteMessage("***Error in getting a point, exiting!!***" + "/r/n");
   return;
   } // 如果獲取一個點
  
  }
  
  7) 上面的代碼只提示輸入名字,請加入提示輸入薪水和部門的代碼。
  8) 完成提示輸入后,我們將使用獲得的值來創建雇員。
  //創建雇員
  CreateEmployee(empName, divName, salary, position);
   //www.survivalescaperooms.com
  9) 現在來檢查部門經理是否已存在。我們通過檢查NOD中部門的擴展記錄中的經理名字來進行。如果檢查到的是一個空字符串,那么我們會提示用戶輸入經理的名字。注意,通過修改CreateDivision()函數,獲取經理的名字變得簡單了。
  string manager = "";
  //創建部門
  //給經理傳入一個空字符串來檢查它是否已存在
  Xrecord depMgrXRec;
  ObjectId xRecId;
  xRecId = CreateDivision(divName, manager);
  //打開部門經理擴展記錄
  depMgrXRec = (Xrecord)trans.GetObject(xRecId, OpenMode.ForRead);
  TypedValue[] typedVal = depMgrXRec.Data.AsArray();
  foreach (TypedValue val in typedVal)
  {
   string str;
   str = (string)val.Value;
   if (str == "")
   {
   //經理沒有被設置,現在設置它
   // 先提示輸入經理的名字
   ed.WriteMessage("/r/n");
   PromptStringOptions prManagerName = new PromptStringOptions("No manager set for the division! Enter Manager Name");
   prManagerName.AllowSpaces = true;
   PromptResult prManagerNameRes = ed.GetString(prManagerName);
   if (prManagerNameRes.Status != PromptStatus.OK)
   {
   return;
   }
   //設置經理的名字
   depMgrXRec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, prManagerNameRes.StringResult));
   }
  }
  
  
  
  10) 測試CREATE命令
  
  選擇集:
  現在讓我們來創建一個命令,當用戶在圖形中選擇一個雇員對象時,它會顯示雇員的詳細資料。
  我們會使用上一章中創建的ListEmployee()函數在命令行中輸出雇員的詳細資料。
  下面是你必須遵循的步驟:
  調用“LISTEMPLOYEES”命令
  調用Editor的GetSelection()函數來選擇實體
   PromptSelectionResult res = ed.GetSelection(Opts, filter);
  
  上面的filter用來過濾選擇集中的塊索引。你可以創建如下的過濾列表:
  TypedValue[] filList = new TypedValue[1];
  filList[0] = new TypedValue((int)DxfCode.Start, "INSERT");
  SelectionFilter filter = new SelectionFilter(filList);
  
  從選擇集中獲取ObjectId數組:
  
   //如果選擇失敗則什么也不做
   if (res.Status != PromptStatus.OK)
   return;
   Autodesk.AutoCAD.EditorInput.SelectionSet SS = res.Value;
   ObjectId[] idArray;
   idArray = SS.GetObjectIds();
  
  5. 最后,把選擇集中的每個ObjectId輸入到ListEmployee()函數來獲取一個雇員詳細資料的字符串數組。把雇員的詳細資料輸出到命令行。例如:
  
  //獲取saEmployeeList 數組中的所有雇員
  foreach (ObjectId employeeId in idArray)
  {
   ListEmployee(employeeId, ref saEmployeeList);
   //把雇員的詳細資料輸出到命令行
   foreach (string employeeDetail in saEmployeeList)
   {
   ed.WriteMessage(employeeDetail);
   }
  
   ed.WriteMessage("----------------------" + "/r/n");
  }
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 曲靖市| 铜陵市| 托里县| 凤山市| 普格县| 广南县| 新兴县| 恩施市| 临泉县| 思南县| 深水埗区| 邢台市| 衡阳市| 涿州市| 陕西省| 玉屏| 都匀市| 海原县| 邛崃市| 天等县| 天祝| 宁晋县| 嵊州市| 武定县| 佳木斯市| 乌拉特中旗| 将乐县| 化州市| 买车| 长宁区| 乐都县| 秦皇岛市| 黄石市| 临漳县| 临颍县| 双鸭山市| 电白县| 电白县| 大姚县| 古丈县| 富宁县|