Using a modeless .NET dialog to display AutoCAD object properties

 

In this previous post we looked at creating a simple modal dialog and using it to display object properties. This post looks at the structural changes you need to make to your application for the same dialog to be used modelessly. In a later post we'll look at the benefits you get from leveraging the Palette system for modeless interaction inside AutoCAD.

Firstly, let's think about the interaction paradigm needed by a modeless dialog. A few things come to mind:

  • There is no longer a need to hide and show the dialog around selection
  • Rather than asking the user to select an entity, it's neater to respond to standard selection events
  • We no longer need a "browse" button
  • We now need to be more careful about document access
    • Our command automatically locked the document (and had sole access) in the modal example
    • We should now lock it "manually" when we access it

So we can already simplify our dialog class - here's some modified C# code, with the browse button removed and document-locking in place:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;


namespace CustomDialogs

{

  public partial class TypeViewerForm : Form

  {

    public TypeViewerForm()

    {

      InitializeComponent();

    }


    public void SetObjectText(string text)

    {

      typeTextBox.Text = text;

    }


    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();

          }

        }

      }

    }

    private void closeButton_Click(object sender, EventArgs e)

    {

      this.Close();

    }

  }

}

So which event should we respond to, to find out when objects are selected? In this case I chose a PointMonitor - this class tells you a lot of really useful information about the current selection process. It also has the advantage of picking up the act of hovering over objects - no need for selection to actually happen. One other fun option would have been to use a Database event (ObjectAppended) to display information about objects as they are added to the drawing.

A few other comments about the code:

  • Predictably enough we now use ShowModelessDialog rather than ShowModalDialog()
  • We have our form as a member variable of the class, as its lifespan goes beyond the command we use to show it
  • I've also removed the selection code; we're no longer asking for objects to be selected

Here's the updated command implementation:

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

  {

    TypeViewerForm tvf;


    public Commands()

    {

      tvf = new TypeViewerForm();

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Editor ed = doc.Editor;

      ed.PointMonitor +=

        new PointMonitorEventHandler(OnMonitorPoint);

    }


    ~Commands()

    {

      try

      {

        tvf.Dispose();

        Document doc =

          Application.DocumentManager.MdiActiveDocument;

        Editor ed = doc.Editor;

        ed.PointMonitor -=

          new PointMonitorEventHandler(OnMonitorPoint);

      }

      catch(System.Exception)

      {

        // The editor may no longer

        // be available on unload

      }

    }


    private void OnMonitorPoint(

      object sender,

      PointMonitorEventArgs e

    )

    {

      FullSubentityPath[] paths =

        e.Context.GetPickedEntities();

      if (paths.Length <= 0)

      {

        tvf.SetObjectId(ObjectId.Null);

        return;

      };


      ObjectId[] objs = paths[0].GetObjectIds();

      if (objs.Length <= 0)

      {

        tvf.SetObjectId(ObjectId.Null);

        return;

      };


      // Set the "selected" object to be the last in the list

      tvf.SetObjectId(objs[objs.Length - 1]);

    }


    [CommandMethod("vt",CommandFlags.UsePickSet)]

    public void ViewType()

    {

      Application.ShowModelessDialog(null, tvf, false);

    }

  }

}

And here's the source project for this version of the application. When you run the application you may experience issues with the dialog getting/retaining focus - this is generally a problem with modeless dialogs that has been addressed automatically by the Palette class, something we'll take a look at in a future post.

June 29, 2007 in AutoCAD, AutoCAD .NET | Permalink

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/t/trackback/876965/19608714

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值