非模态窗口有一个好处,就是可以一直停留在程序之前,然后持续完成操作。但是在Revit二次开发中,非模态窗口也有几个注意事项。
1、需要在文档关闭的时候,把非模态窗口也关闭掉,不然会导致文档关闭,窗口还在这样奇怪的Bug。
2、非模态的窗口的事件需要在IExternalCommand里注册。
3、每个操作必须在外部事件里进行。
以下代码关注后两个注意事项,第一个用上Document事件即可解决。
首先在IExternalCommand注册事件。
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;
}
}
}
然后写一个通用的外部事件。
public class ExecuteEventHandler : IExternalEventHandler
{
public string Name { get;private set; }
public Action 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;
}
}
接下来,通过控件来实现创建构件。
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((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((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();
}
}
}
这就是一个简单的非模态窗口实现的办法。
对Revit二次开发和Dyanmo编程这块感兴趣请加qq群交流:660319009
个人问题咨询请加qq:254033230,本人见钱眼开,不要轻易打扰!!!