天天看點

用.NET的面闆來顯示多個AutoCAD實體的屬性

原文:Using a palette from .NET to display properties of multiple AutoCAD objects

本文僅翻譯部分内容

經過短暫的插曲,我們又回到了示範如何用.NET在AutoCAD中實作基本使用者界面的系列文章。這是目前為止該系列的文章清單:

  • Using a modal .NET dialog to display AutoCAD object properties
  • Using a modeless .NET dialog to display AutoCAD object properties
  • Using a modeless .NET dialog to display properties of multiple AutoCAD objects

在這篇文章中我們将換掉已經在前幾篇系列文章中使用的無模式對話框,用AutoCAD内置的palette類(Autodesk.AutoCAD.Windows.PaletteSet)為例來替換它。

為什麼要用Paletteset類呢?因為Paletteset類非常炫酷:它提供了停靠(docking),自動隐藏,支援透明度并且修複了我們在無模式對話框中遇到的惱人的焦點相關的問題。

最重要的是,實作這一切基本上不需要花費任何代價——實作它的工作幾乎最小的。我從ObjectARX SDK的DockingPalette的示例中複制了大部分的代碼,然後删除了我們項目不需要的部分。

下面是更新後的指令的實作。修改真的非常小,因為palette的實作都隐藏在新的TypeViewerPalette類裡了。

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System;
using CustomDialogs;

namespace CustomDialogs
{
  public class Commands : IExtensionApplication
  {
    static TypeViewerPalette tvp;

    public void Initialize()
    {
      tvp = new TypeViewerPalette();

      DocumentCollection dm =
        Application.DocumentManager;
      dm.DocumentCreated +=
        new DocumentCollectionEventHandler(OnDocumentCreated);
      foreach (Document doc in dm)
      {
        doc.Editor.PointMonitor +=
          new PointMonitorEventHandler(OnMonitorPoint);
      }
    }

    public void Terminate()
    {
      try
      {
        DocumentCollection dm =
          Application.DocumentManager;
        if (dm != null)
        {
          Editor ed = dm.MdiActiveDocument.Editor;
          ed.PointMonitor -=
            new PointMonitorEventHandler(OnMonitorPoint);
        }
      }
      catch (System.Exception)
      {
        // The editor may no longer
        // be available on unload
      }
    }

    private void OnDocumentCreated(
      object sender,
      DocumentCollectionEventArgs e
    )
    {
      e.Document.Editor.PointMonitor +=
        new PointMonitorEventHandler(OnMonitorPoint);
    }

    private void OnMonitorPoint(
      object sender,
      PointMonitorEventArgs e
    )
    {
      FullSubentityPath[] paths =
        e.Context.GetPickedEntities();
      if (paths.Length <= 0)
      {
        tvp.SetObjectId(ObjectId.Null);
        return;
      };

      ObjectIdCollection idc = new ObjectIdCollection();
      foreach (FullSubentityPath path in paths)
      {
        // Just add the first ID in the list from each path
        ObjectId[] ids = path.GetObjectIds();
        idc.Add(ids[0]);
      }
      tvp.SetObjectIds(idc);
    }

    [CommandMethod("vt",CommandFlags.UsePickSet)]
    public void ViewType()
    {
      tvp.Show();
    }
  }
}
           

至于TypeViewerPalette類:我通過從原來的TypeViewerForm類中把SetObjectId[s]()/SetObjectText() 協定遷移過來開始——這是其中最複雜的一部分,涉及通過一個可以從SetObjectText()成員變量暴露我們的面闆的内容(我們作為一個使用者控件定義并加載)。除了前面說的以外,其它的就隻是複制和粘貼了。

這是C #代碼:

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
using Autodesk.AutoCAD.Windows;
using TypeViewer;

namespace CustomDialogs
{
  public class TypeViewerPalette
  {
    // We cannot derive from PaletteSet
    // so we contain it
    static PaletteSet ps;

    // We need to make the textbox available
    // via a static member
    static TypeViewerControl tvc;

    public TypeViewerPalette()
    {
      tvc = new TypeViewerControl();
    }

    public void Show()
    {
      if (ps == null)
      {
        ps = new PaletteSet("Type Viewer");
        ps.Style =
          PaletteSetStyles.NameEditable |
          PaletteSetStyles.ShowPropertiesMenu |
          PaletteSetStyles.ShowAutoHideButton |
          PaletteSetStyles.ShowCloseButton;
        ps.MinimumSize =
          new System.Drawing.Size(300, 300);
        ps.Add("Type Viewer 1", tvc);
      }
      ps.Visible = true;
    }

    public void SetObjectText(string text)
    {
      tvc.typeTextBox.Text = text;
    }

    public void SetObjectIds(ObjectIdCollection ids)
    {
      if (ids.Count < 0)
      {
        SetObjectText("");
      }
      else
      {
        Document doc =
          Autodesk.AutoCAD.ApplicationServices.
            Application.DocumentManager.MdiActiveDocument;
        DocumentLock loc =
          doc.LockDocument();
        using (loc)
        {
          string info =
            "Number of objects: " +
            ids.Count.ToString() + "\r\n";
          Transaction tr =
            doc.TransactionManager.StartTransaction();
          using (tr)
          {
            foreach (ObjectId id in ids)
            {
              Entity ent =
                (Entity)tr.GetObject(id, OpenMode.ForRead);
              Solid3d sol = ent as Solid3d;
              if (sol != null)
              {
                Acad3DSolid oSol =
                  (Acad3DSolid)sol.AcadObject;

                // Put in a try-catch block, as it's possible
                // for solids to not support this property,
                // it seems (better safe than sorry)
                try
                {
                  string solidType = oSol.SolidType;
                  info +=
                    ent.GetType().ToString() +
                    " (" + solidType + ") : " +
                    ent.ColorIndex.ToString() + "\r\n";
                }
                catch (System.Exception)
                {
                  info +=
                    ent.GetType().ToString() +
                    " : " +
                    ent.ColorIndex.ToString() + "\r\n";
                }
              }
              else
              {
                info +=
                  ent.GetType().ToString() +
                  " : " +
                  ent.ColorIndex.ToString() + "\r\n";
              }
            }
            tr.Commit();
          }
          SetObjectText(info);
        }
      }
    }

    public void SetObjectId(ObjectId id)
    {
      if (id == ObjectId.Null)
      {
        SetObjectText("");
      }
      else
      {
        Document doc =
          Autodesk.AutoCAD.ApplicationServices.
            Application.DocumentManager.MdiActiveDocument;
        DocumentLock loc =
          doc.LockDocument();
        using (loc)
        {
          Transaction tr =
            doc.TransactionManager.StartTransaction();
          using (tr)
          {
            DBObject obj =
              tr.GetObject(id, OpenMode.ForRead);
            SetObjectText(obj.GetType().ToString());
            tr.Commit();
          }
        }
      }
    }
  }
}
           

你可以從 這裡下載下傳源碼

繼續閱讀