เขียน Command แรก
โครงสร้างพื้นฐาน
Section titled “โครงสร้างพื้นฐาน”เริ่มต้นให้คุณสร้างไฟล์ชื่อ Command.cs ในโปรเจ็กต์ และใส่โค้ดตั้งต้นนี้ลงไปครับ:
using Autodesk.Revit.Attributes;using Autodesk.Revit.DB;using Autodesk.Revit.UI;
namespace RevitToolkit;
// 1. TransactionMode.Manual: เราจะจัดการการบันทึกสถานะ (แก้ไขโมเดล) ด้วยตัวเอง[Transaction(TransactionMode.Manual)]public class Command : IExternalCommand // 2. คลาสถูกสืบทอดจาก IExternalCommand เสมอ{ // 3. ฟังก์ชันการทำงานหลัก (Entry Point) public Result Execute( ExternalCommandData commandData, // เก็บข้อมูลเกี่ยวกับ Application ปัจจุบัน (เอกสารที่เปิดอยู่) ref string message, // ตัวแปรเก็บค่า error หากประมวลผลล้มเหลว ElementSet elements) // สำหรับทำไฮไลท์ element เวลาเกิด error { // 4. แสดงผลทดสอบที่หน้าจอ TaskDialog.Show("RevitToolkit", "Hello from Revit 2026");
// 5. ส่งกลับบอก Revit ว่างานสำเร็จ return Result.Succeeded; }}🔍 ชำแหละโครงสร้างคลาสและเจาะลึก Revit API ที่ใช้
Section titled “🔍 ชำแหละโครงสร้างคลาสและเจาะลึก Revit API ที่ใช้”ในโค้ด C# สำหรับคำสั่งแรกนี้ มีองค์ประกอบสำคัญของ Revit API ที่ผู้อ่านควรรู้จักเป็นอย่างดี ดังนี้ครับ:
1. IExternalCommand (Interface)
Section titled “1. IExternalCommand (Interface)”- มันคืออะไร: เป็นอินเทอร์เฟซหลักของ Autodesk Revit สำหรับกำหนดประเภทวัตถุที่จะทำหน้าที่รับสั่งรันคำสั่งเมื่อผู้ใช้กดปุ่ม
- หน้าที่ในโค้ด: คลาสใดก็ตามที่ผู้ใช้งานต้องการให้เป็น “ปุ่มกดเครื่องมือย่อย” จะต้องทำการสืบทอด (
: IExternalCommand) เสมอ เพื่อเป็นช่องทางให้ Revit ทราบจุดเริ่มต้นรันงาน - ทำไมต้องใช้: หากเราสร้างคลาสปกติขึ้นมาเดี่ยวๆ โดยไม่ต่ออินเทอร์เฟซนี้ Revit จะมองข้ามและไม่สามารถโหลดชุดคำสั่งของเราไปประมวลผลได้เลยครับ
2. Execute (Method Entry Point)
Section titled “2. Execute (Method Entry Point)”- มันคืออะไร: ฟังก์ชันทางเข้าหลัก (Entry Point) ที่ประกาศไว้ในอินเทอร์เฟซ
IExternalCommand - หน้าที่ในโค้ด: จะถูกเรียกใช้งานโดยอัตโนมัติจาก Thread หลักของระบบ Revit ทันทีที่มีการกดปุ่มสั่งงานบนหน้าจอ โดยมีพารามิเตอร์ส่งต่อดังนี้:
ExternalCommandData commandData: เปรียบเสมือน “กล่องเก็บของเล่นสารพัดประโยชน์” ที่ให้เราดึงข้อมูลแอปพลิเคชัน ตัวแทนไฟล์งานที่เปิดอยู่ (Document) หรือชุดสกรีนพิกัดการเลือกวัตถุของผู้ใช้ (Selection)ref string message: ตัวแปรส่งผ่านข้อความ หากปลั๊กอินของเราทำงานไม่สำเร็จ (คืนค่าเป็นResult.Failed) ข้อความใดๆ ที่เราฝากเขียนไว้ในตัวแปรนี้จะไปปรากฏเป็นกล่องแจ้งเตือนความผิดพลาดบนหน้าจอ Revit ทันทีElementSet elements: ตัวแทนเซตของวัตถุ กรณีปลั๊กอินทำงานล้มเหลว เราสามารถยัดโมเดลที่มีปัญหาใส่ในชุดนี้เพื่อให้ Revit ช่วยเปลี่ยนสีวัตถุเหล่านั้นให้เป็นสีแดงเพื่อช่วยเตือนผู้ใช้ได้
3. Result (Enum)
Section titled “3. Result (Enum)”- มันคืออะไร: ค่าแจกแจงผลการทำงานส่งกลับหลังประมวลผลคำสั่งสำเร็จ
- หน้าที่ในโค้ด: คืนค่าเพื่อบอกสถานะกับระบบประวัติคำสั่งของ Revit:
Result.Succeeded: การทำงานไร้ปัญหา ระบบจะอัปเดตโมเดลเข้าประวัติResult.Failed: งานทำงานล้มเหลวหรือเกิดข้อผิดพลาด ปลั๊กอินจะหยุดตัวพร้อมยกเลิกการปรับปรุงResult.Cancelled: ผู้ใช้กดปุ่มยกเลิกคำสั่งกลางคัน
- ทำไมต้องใช้: เพื่อช่วยให้โปรแกรมบริหารจัดการชุดประวัติการกด Undo/Redo ในไฟล์ได้อย่างเรียบร้อยและไม่ค้างคาในอนาคต
4. [Transaction(TransactionMode.Manual)] (Attribute)
Section titled “4. [Transaction(TransactionMode.Manual)] (Attribute)”- มันคืออะไร: แอตทริบิวต์กำหนดโหมดรักษาความปลอดภัยของการเขียนฐานข้อมูล Revit
- หน้าที่ในโค้ด: บอกให้ Revit ทราบว่าคลาส C# ชุดนี้จะขอยืนยัน “เปิด-ปิด และบันทึกประวัติ Transaction ด้วยน้ำมือตัวเองเท่านั้น (Manual)”
- ทำไมต้องใช้: ปัจจุบัน Autodesk กำหนดให้ใช้วิธีนี้เพื่อให้เขียนโค้ดคลุมความปลอดภัยครอบการแก้ไขไฟล์ ป้องกันข้อมูลของโปรเจ็กต์เสียหาย
5. TaskDialog (Class)
Section titled “5. TaskDialog (Class)”- มันคืออะไร: กล่องหน้าต่างแจ้งเตือนเฉพาะทางของโปรแกรม Revit
- หน้าที่ในโค้ด: สั่งเปิด Popup ข้อความสีฟ้าเพื่อเช็กสถานะการโหลดได้อย่างรวดเร็ว โดยคำสั่ง
TaskDialog.Show("หัวข้อ", "รายละเอียดข้อความ")จะช่วยอำนวยความสะดวกในการแสดงผลงานช่วงต้นโดยไม่ต้องวาดหน้าจอ UI ซับซ้อนด้วยตนเอง