用.NET的面板来显示多个AutoCAD实体的属性

翻译 2013年12月04日 00:10:40

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

本文仅翻译部分内容

经过短暂的插曲,我们又回到了演示如何用.NET在AutoCAD中实现基本用户界面的系列文章。这是目前为止该系列的文章列表:

在这篇文章中我们将换掉已经在前几篇系列文章中使用的无模式对话框,用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();
          }
        }
      }
    }
  }
}
你可以从这里下载源码

相关文章推荐

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

After a brief interlude were back on the series of posts showing how to implement basic user-interf...
  • sdphg
  • sdphg
  • 2007年07月20日 16:22
  • 1555

在.NET中进行AutoCAD二次开发(C#+ObjectArx)

1.Autodesk官方最新的.net教程(一)(C#版):修正:(1)启用对象浏览器方法:双击托管的类,会自动调用对象浏览器(2)调试环境设置:应设2项,否则调试程序无法运行:启动外部程序为:F:/...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

03-04 创建和编辑AutoCAD实体(四) 编辑二维命名对象 (9)

11、Edit Hatches 编辑图案填充 You can edit both hatch boundaries and hatch patterns. If you edit the bound...

C#中使用Property Grid(属性面板)控件

1.将Property Grid 控件添加到工具箱中由于默认情况下Property Grid 控件没有显示在工具箱中所以需要手动添加。 图1 将Property Grid添加到工具箱(在工具箱上右键选...
  • zilin82
  • zilin82
  • 2010年09月03日 00:54
  • 2802

AutoCAD.NET获取实体的ExtendedDataAsciiString扩展数据信息

public string GetXData(ObjectId entId) { Editor ed = Autodesk.AutoCAD.Applicatio...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

CAD.net 创建面板

1、使用注册表进行插件dll的自动加载时Autodesk.Windows.ComponentManager.Ribbon == null需要延迟一下再调用面板的创建代码 2、注册事件Autodesk....

CAD的Dock窗口创建

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源) 参考: http://www.cnblogs.com/oneday/p/3413...

auto CAD .NET二次开发之 添加,删除实体(entity)

个人感觉添加删除实体这个方法比较水。只要是操作过CAD的.NET程序员都是小菜一碟。不过在这里还是赘述一下。呵呵 添加实体的核心代码只有两句:                           ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用.NET的面板来显示多个AutoCAD实体的属性
举报原因:
原因补充:

(最多只允许输入30个字)