非模态窗口有一个好处,就是可以一直停留在程序之前,然后持续完成操作。但是在Revit二次开发中,非模态窗口也有几个注意事项。
1、需要在文档关闭的时候,把非模态窗口也关闭掉,不然会导致文档关闭,窗口还在这样奇怪的Bug。
2、非模态的窗口的事件需要在IExternalCommand里注册。
3、每个操作必须在外部事件里进行。
以下代码关注后两个注意事项,第一个用上Document事件即可解决。
首先在IExternalCommand注册事件。
[html] view plain copy
- public class Command : IExternalCommand
- {
- public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
- {
- try
- {
- ExecuteEventHandler executeEventHandler = new ExecuteEventHandler("Creat Model Line");
- ExternalEvent externalEvent = ExternalEvent.Create(executeEventHandler);
- // show UI
- ModelessView modelessView = new ModelessView(executeEventHandler, externalEvent);
- //窗口一直显示在主程序之前
- System.Windows.Interop.WindowInteropHelper mainUI = new System.Windows.Interop.WindowInteropHelper(modelessView);
- mainUI.Owner = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
- modelessView.Show();
- return Autodesk.Revit.UI.Result.Succeeded;
- }
- catch (Exception e)
- {
- message = e.Message;
- return Autodesk.Revit.UI.Result.Failed;
- }
- }
- }
然后写一个通用的外部事件。
[csharp] view plain copy
- public class ExecuteEventHandler : IExternalEventHandler
- {
- public string Name { get;private set; }
- public Action<UIApplication> ExecuteAction { get; set; }
- public ExecuteEventHandler(string name)
- {
- Name = name;
- }
- public void Execute(UIApplication app)
- {
- if(ExecuteAction!=null)
- {
- try
- {
- ExecuteAction(app);
- }
- catch
- { }
- }
- }
- public string GetName()
- {
- return Name;
- }
- }
接下来,通过控件来实现创建构件。
[csharp] view plain copy
- public partial class ModelessView : Window
- {
- ExecuteEventHandler _executeEventHandler= null;
- ExternalEvent _externalEvent = null;
- public ModelessView(ExecuteEventHandler executeEventHandler,ExternalEvent externalEvent)
- {
- InitializeComponent();
- _executeEventHandler = executeEventHandler;
- _externalEvent = externalEvent;
- }
- private void creatLine_Click(object sender, RoutedEventArgs e)
- {
- if(_externalEvent!=null)
- {
- _executeEventHandler.ExecuteAction = new Action<UIApplication>((app) =>
- {
- if (app.ActiveUIDocument == null || app.ActiveUIDocument.Document == null)
- return;
- Document revitDoc = app.ActiveUIDocument.Document;
- using (Transaction transaction=new Transaction(revitDoc,"Creat Line1"))
- {
- transaction.Start();
- Autodesk.Revit.DB.Line line = Autodesk.Revit.DB.Line.CreateBound(new XYZ(0, 0, 0), new XYZ(100, 0, 0));
- SketchPlane sketchPlane = SketchPlane.Create(revitDoc, Plane.CreateByNormalAndOrigin(XYZ.BasisZ, XYZ.Zero));
- revitDoc.Create.NewModelCurve(line as Curve, sketchPlane);
- transaction.Commit();
- }
- });
- _externalEvent.Raise();
- }
- }
- private void creatLine2_Click(object sender, RoutedEventArgs e)
- {
- if (_externalEvent != null)
- {
- _executeEventHandler.ExecuteAction = new Action<UIApplication>((app) =>
- {
- if (app.ActiveUIDocument == null || app.ActiveUIDocument.Document == null)
- return;
- Document revitDoc = app.ActiveUIDocument.Document;
- using (Transaction transaction = new Transaction(revitDoc, "Creat Line2"))
- {
- transaction.Start();
- Autodesk.Revit.DB.Line line = Autodesk.Revit.DB.Line.CreateBound(new XYZ(0, 100, 0), new XYZ(100, 100, 0));
- SketchPlane sketchPlane = SketchPlane.Create(revitDoc, Plane.CreateByNormalAndOrigin(XYZ.BasisZ, XYZ.Zero));
- revitDoc.Create.NewModelCurve(line as Curve, sketchPlane);
- transaction.Commit();
- }
- });
- _externalEvent.Raise();
- }
- }
- }
这就是一个简单的非模态窗口实现的办法。