So i was looking at Jeremy's sample post about modeless forms and was trying to modify one of the examples to do something other than flip the door. Here's my attempt and an issue it generated.
For some reason when I try to execute the DeleteViews() method which should be triggered by RequestId.TurnIn what happens is that both of the functions defined below get executed: DeleteSheets and DeleteViews.
Is there a way to assign separate function calls to each button?
Thanks!
// // (C) Copyright 2003-2015 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // using System; using System.Collections.Generic; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using System.Linq; namespace Revit.SDK.Samples.ModelessForm_ExternalEvent.CS { /// <summary> /// A class with methods to execute requests made by the dialog user. /// </summary> /// public class RequestHandler : IExternalEventHandler { // A trivial delegate, but handy private delegate void DoorOperation(FamilyInstance e); // The value of the latest request made by the modeless form private Request m_request = new Request(); /// <summary> /// A public property to access the current request value /// </summary> public Request Request { get { return m_request; } } /// <summary> /// A method to identify this External Event Handler /// </summary> public String GetName() { return "R2014 External Event Sample"; } /// <summary> /// The top method of the event handler. /// </summary> /// <remarks> /// This is called by Revit after the corresponding /// external event was raised (by the modeless form) /// and Revit reached the time at which it could call /// the event's handler (i.e. this object) /// </remarks> /// public void Execute(UIApplication uiapp) { try { switch (Request.Take()) { case RequestId.None: { return; // no request at this time -> we can leave immediately } case RequestId.Delete: { DeleteSheets(uiapp, "Delete sheets"); //ModifySelectedDoors(uiapp, "Delete sheets", e => e.Document.Delete(e.Id)); break; } //case RequestId.FlipLeftRight: // { // ModifySelectedDoors(uiapp, "Flip door Hand", e => e.flipHand()); // break; // } //case RequestId.FlipInOut: // { // ModifySelectedDoors(uiapp, "Flip door Facing", e => e.flipFacing()); // break; // } //case RequestId.MakeLeft: // { // ModifySelectedDoors(uiapp, "Make door Left", MakeLeft); // break; // } //case RequestId.MakeRight: // { // ModifySelectedDoors(uiapp, "Make door Right", MakeRight); // break; // } //case RequestId.TurnOut: // { // ModifySelectedDoors(uiapp, "Place door Out", TurnOut); // break; // } case RequestId.TurnIn: { DeleteViews(uiapp, "Place door In"); break; } //case RequestId.Rotate: // { // ModifySelectedDoors(uiapp, "Rotate door", FlipHandAndFace); // break; // } default: { // some kind of a warning here should // notify us about an unexpected request break; } } } finally { Application.thisApp.WakeFormUp(); } return; } /// <summary> /// The main door-modification subroutine - called from every request /// </summary> /// <remarks> /// It searches the current selection for all doors /// and if it finds any it applies the requested operation to them /// </remarks> /// <param name="uiapp">The Revit application object</param> /// <param name="text">Caption of the transaction for the operation.</param> /// private void DeleteSheets(UIApplication uiapp, String text) { UIDocument uidoc = uiapp.ActiveUIDocument; if (uidoc != null) { ICollection<ElementId> allSheets = new FilteredElementCollector(uidoc.Document) .OfClass(typeof(ViewSheet)) .ToElementIds(); using (Transaction trans = new Transaction(uidoc.Document)) { if (trans.Start(text) == TransactionStatus.Started) { foreach (ElementId id in allSheets) { uidoc.Document.Delete(id); } trans.Commit(); } } } } private void DeleteViews(UIApplication uiapp, String text) { UIDocument uidoc = uiapp.ActiveUIDocument; if (uidoc != null) { using (Transaction trans = new Transaction(uidoc.Document)) { if (trans.Start(text) == TransactionStatus.Started) { try { View currentView = uidoc.ActiveView; List<ElementId> exclude = new List<ElementId>(); exclude.Add(currentView.Id); ExclusionFilter filter = new ExclusionFilter(exclude); IList<Element> collection = new FilteredElementCollector(uidoc.Document).OfClass(typeof(View)).WherePasses(filter).ToElements(); for (var i = 0; i < collection.Count; i++) { View v = collection[i] as View; if (v.Name == "Project View") { collection.RemoveAt(i); } } int x = 0; foreach (Element e in collection) { try { View view = e as View; // all views/sheets are deleted and increment counter by 1 uidoc.Document.Delete(view.Id); x += 1; } catch (Exception ex) { TaskDialog.Show("Error", ex.Message); } } trans.Commit(); TaskDialog.Show("DeleteAllSheetsViews", "Views & Sheets Deleted: " + x.ToString()); } catch (Exception ex) { TaskDialog.Show("Error", ex.Message); } } } } } ////////////////////////////////////////////////////////////////////////// // // Helpers - simple delegates operating upon an instance of a door private void FlipHandAndFace(FamilyInstance e) { e.flipFacing(); e.flipHand(); } // Note: The door orientation [left/right] is according the common // conventions used by the building industry in the Czech Republic. // If the convention is different in your county (like in the U.S), // swap the code of the MakeRight and MakeLeft methods. private static void MakeLeft(FamilyInstance e) { if (e.FacingFlipped ^ e.HandFlipped) e.flipHand(); } private void MakeRight(FamilyInstance e) { if (!(e.FacingFlipped ^ e.HandFlipped)) e.flipHand(); } // Note: The In|Out orientation depends on the position of the // wall the door is in; therefore it does not necessary indicates // the door is facing Inside, or Outside, respectively. // The presented implementation is good enough to demonstrate // how to flip a door, but the actual algorithm will likely // have to be changes in a read-world application. private void TurnIn(FamilyInstance e) { if (!e.FacingFlipped) e.flipFacing(); } private void TurnOut(FamilyInstance e) { if (e.FacingFlipped) e.flipFacing(); } } // class } // namespace
Solved! Go to Solution.
So i was looking at Jeremy's sample post about modeless forms and was trying to modify one of the examples to do something other than flip the door. Here's my attempt and an issue it generated.
For some reason when I try to execute the DeleteViews() method which should be triggered by RequestId.TurnIn what happens is that both of the functions defined below get executed: DeleteSheets and DeleteViews.
Is there a way to assign separate function calls to each button?
Thanks!
// // (C) Copyright 2003-2015 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // using System; using System.Collections.Generic; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using System.Linq; namespace Revit.SDK.Samples.ModelessForm_ExternalEvent.CS { /// <summary> /// A class with methods to execute requests made by the dialog user. /// </summary> /// public class RequestHandler : IExternalEventHandler { // A trivial delegate, but handy private delegate void DoorOperation(FamilyInstance e); // The value of the latest request made by the modeless form private Request m_request = new Request(); /// <summary> /// A public property to access the current request value /// </summary> public Request Request { get { return m_request; } } /// <summary> /// A method to identify this External Event Handler /// </summary> public String GetName() { return "R2014 External Event Sample"; } /// <summary> /// The top method of the event handler. /// </summary> /// <remarks> /// This is called by Revit after the corresponding /// external event was raised (by the modeless form) /// and Revit reached the time at which it could call /// the event's handler (i.e. this object) /// </remarks> /// public void Execute(UIApplication uiapp) { try { switch (Request.Take()) { case RequestId.None: { return; // no request at this time -> we can leave immediately } case RequestId.Delete: { DeleteSheets(uiapp, "Delete sheets"); //ModifySelectedDoors(uiapp, "Delete sheets", e => e.Document.Delete(e.Id)); break; } //case RequestId.FlipLeftRight: // { // ModifySelectedDoors(uiapp, "Flip door Hand", e => e.flipHand()); // break; // } //case RequestId.FlipInOut: // { // ModifySelectedDoors(uiapp, "Flip door Facing", e => e.flipFacing()); // break; // } //case RequestId.MakeLeft: // { // ModifySelectedDoors(uiapp, "Make door Left", MakeLeft); // break; // } //case RequestId.MakeRight: // { // ModifySelectedDoors(uiapp, "Make door Right", MakeRight); // break; // } //case RequestId.TurnOut: // { // ModifySelectedDoors(uiapp, "Place door Out", TurnOut); // break; // } case RequestId.TurnIn: { DeleteViews(uiapp, "Place door In"); break; } //case RequestId.Rotate: // { // ModifySelectedDoors(uiapp, "Rotate door", FlipHandAndFace); // break; // } default: { // some kind of a warning here should // notify us about an unexpected request break; } } } finally { Application.thisApp.WakeFormUp(); } return; } /// <summary> /// The main door-modification subroutine - called from every request /// </summary> /// <remarks> /// It searches the current selection for all doors /// and if it finds any it applies the requested operation to them /// </remarks> /// <param name="uiapp">The Revit application object</param> /// <param name="text">Caption of the transaction for the operation.</param> /// private void DeleteSheets(UIApplication uiapp, String text) { UIDocument uidoc = uiapp.ActiveUIDocument; if (uidoc != null) { ICollection<ElementId> allSheets = new FilteredElementCollector(uidoc.Document) .OfClass(typeof(ViewSheet)) .ToElementIds(); using (Transaction trans = new Transaction(uidoc.Document)) { if (trans.Start(text) == TransactionStatus.Started) { foreach (ElementId id in allSheets) { uidoc.Document.Delete(id); } trans.Commit(); } } } } private void DeleteViews(UIApplication uiapp, String text) { UIDocument uidoc = uiapp.ActiveUIDocument; if (uidoc != null) { using (Transaction trans = new Transaction(uidoc.Document)) { if (trans.Start(text) == TransactionStatus.Started) { try { View currentView = uidoc.ActiveView; List<ElementId> exclude = new List<ElementId>(); exclude.Add(currentView.Id); ExclusionFilter filter = new ExclusionFilter(exclude); IList<Element> collection = new FilteredElementCollector(uidoc.Document).OfClass(typeof(View)).WherePasses(filter).ToElements(); for (var i = 0; i < collection.Count; i++) { View v = collection[i] as View; if (v.Name == "Project View") { collection.RemoveAt(i); } } int x = 0; foreach (Element e in collection) { try { View view = e as View; // all views/sheets are deleted and increment counter by 1 uidoc.Document.Delete(view.Id); x += 1; } catch (Exception ex) { TaskDialog.Show("Error", ex.Message); } } trans.Commit(); TaskDialog.Show("DeleteAllSheetsViews", "Views & Sheets Deleted: " + x.ToString()); } catch (Exception ex) { TaskDialog.Show("Error", ex.Message); } } } } } ////////////////////////////////////////////////////////////////////////// // // Helpers - simple delegates operating upon an instance of a door private void FlipHandAndFace(FamilyInstance e) { e.flipFacing(); e.flipHand(); } // Note: The door orientation [left/right] is according the common // conventions used by the building industry in the Czech Republic. // If the convention is different in your county (like in the U.S), // swap the code of the MakeRight and MakeLeft methods. private static void MakeLeft(FamilyInstance e) { if (e.FacingFlipped ^ e.HandFlipped) e.flipHand(); } private void MakeRight(FamilyInstance e) { if (!(e.FacingFlipped ^ e.HandFlipped)) e.flipHand(); } // Note: The In|Out orientation depends on the position of the // wall the door is in; therefore it does not necessary indicates // the door is facing Inside, or Outside, respectively. // The presented implementation is good enough to demonstrate // how to flip a door, but the actual algorithm will likely // have to be changes in a read-world application. private void TurnIn(FamilyInstance e) { if (!e.FacingFlipped) e.flipFacing(); } private void TurnOut(FamilyInstance e) { if (e.FacingFlipped) e.flipFacing(); } } // class } // namespace
Solved! Go to Solution.
Solved by sobon.konrad. Go to Solution.
The sample is actually included in the SDK.
I am afraid you missed an important part of the code. At the event of pressing a button in the dialog, the Id of the request is set. One specific Id per each executable button. Thus I suppose you did not set the request Id correctly there either for your Delete button or the TurnIn button.
The sample is actually included in the SDK.
I am afraid you missed an important part of the code. At the event of pressing a button in the dialog, the Id of the request is set. One specific Id per each executable button. Thus I suppose you did not set the request Id correctly there either for your Delete button or the TurnIn button.
I left the settings of the form and Id setting as it was. When you hit Delete Button it will set the id to Delete just like it was. I am trying to change the actual method that this call executes by changing its name to DeleteSheets and then defning a new method called DeleteSheets.
Issue is that when I hit Delete Button it tries to execute BOTH of the methods defined: DeleteSheets and DeleteViews.
How would I tie a different method to each button?
Thank you,
I left the settings of the form and Id setting as it was. When you hit Delete Button it will set the id to Delete just like it was. I am trying to change the actual method that this call executes by changing its name to DeleteSheets and then defning a new method called DeleteSheets.
Issue is that when I hit Delete Button it tries to execute BOTH of the methods defined: DeleteSheets and DeleteViews.
How would I tie a different method to each button?
Thank you,
Konrad,
did you debug it? Put a break point to both the Delete and TurnIn case block and see what makes the calls when the breakpoints are hit.
Konrad,
did you debug it? Put a break point to both the Delete and TurnIn case block and see what makes the calls when the breakpoints are hit.
This is what i get when i hit the FlipIn button:
Request that comes through is # 7 so its correct:
It then expectedly jumps to case RequestId.TurnIn: where DeleteViews (uiapp, "") should be executed:
so far everything as expected:
Then exceptiosn start coming in:
But then all my Sheets and Views are gone as if both methods were executed:
Thank you,
This is what i get when i hit the FlipIn button:
Request that comes through is # 7 so its correct:
It then expectedly jumps to case RequestId.TurnIn: where DeleteViews (uiapp, "") should be executed:
so far everything as expected:
Then exceptiosn start coming in:
But then all my Sheets and Views are gone as if both methods were executed:
Thank you,
// // (C) Copyright 2003-2015 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // using System; using System.Collections.Generic; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using System.Linq; namespace Revit.SDK.Samples.ModelessForm_ExternalEvent.CS { /// <summary> /// A class with methods to execute requests made by the dialog user. /// </summary> /// public class RequestHandler : IExternalEventHandler { // A trivial delegate, but handy private delegate void DoorOperation(FamilyInstance e); // The value of the latest request made by the modeless form private Request m_request = new Request(); /// <summary> /// A public property to access the current request value /// </summary> public Request Request { get { return m_request; } } /// <summary> /// A method to identify this External Event Handler /// </summary> public String GetName() { return "R2014 External Event Sample"; } /// <summary> /// The top method of the event handler. /// </summary> /// <remarks> /// This is called by Revit after the corresponding /// external event was raised (by the modeless form) /// and Revit reached the time at which it could call /// the event's handler (i.e. this object) /// </remarks> /// public void Execute(UIApplication uiapp) { try { switch (Request.Take()) { case RequestId.None: { return; // no request at this time -> we can leave immediately } case RequestId.Delete: { DeleteSheets(uiapp, "Delete sheets"); //ModifySelectedDoors(uiapp, "Delete sheets", e => e.Document.Delete(e.Id)); break; } //case RequestId.FlipLeftRight: // { // ModifySelectedDoors(uiapp, "Flip door Hand", e => e.flipHand()); // break; // } //case RequestId.FlipInOut: // { // ModifySelectedDoors(uiapp, "Flip door Facing", e => e.flipFacing()); // break; // } //case RequestId.MakeLeft: // { // ModifySelectedDoors(uiapp, "Make door Left", MakeLeft); // break; // } //case RequestId.MakeRight: // { // ModifySelectedDoors(uiapp, "Make door Right", MakeRight); // break; // } //case RequestId.TurnOut: // { // ModifySelectedDoors(uiapp, "Place door Out", TurnOut); // break; // } case RequestId.TurnIn: { DeleteViews(uiapp, "Place door In"); break; } //case RequestId.Rotate: // { // ModifySelectedDoors(uiapp, "Rotate door", FlipHandAndFace); // break; // } default: { // some kind of a warning here should // notify us about an unexpected request break; } } } finally { Application.thisApp.WakeFormUp(); } return; } /// <summary> /// The main door-modification subroutine - called from every request /// </summary> /// <remarks> /// It searches the current selection for all doors /// and if it finds any it applies the requested operation to them /// </remarks> /// <param name="uiapp">The Revit application object</param> /// <param name="text">Caption of the transaction for the operation.</param> /// private void DeleteSheets(UIApplication uiapp, String text) { UIDocument uidoc = uiapp.ActiveUIDocument; if (uidoc != null) { ICollection<ElementId> allSheets = new FilteredElementCollector(uidoc.Document) .OfClass(typeof(ViewSheet)) .ToElementIds(); using (Transaction trans = new Transaction(uidoc.Document)) { if (trans.Start(text) == TransactionStatus.Started) { foreach (ElementId id in allSheets) { uidoc.Document.Delete(id); } trans.Commit(); } } } } /// <summary> /// The main door-modification subroutine - called from every request /// </summary> /// <remarks> /// It searches the current selection for all doors /// and if it finds any it applies the requested operation to them /// </remarks> /// <param name="uiapp">The Revit application object</param> /// <param name="text">Caption of the transaction for the operation.</param> private void DeleteViews(UIApplication uiapp, String text) { UIDocument uidoc = uiapp.ActiveUIDocument; if (uidoc != null) { using (Transaction trans = new Transaction(uidoc.Document)) { if (trans.Start(text) == TransactionStatus.Started) { // create a new drafting view that will be excluded from selection // and will not be deleted. cannot delete all views from project ViewFamilyType viewFamilyType = new FilteredElementCollector(uidoc.Document) .OfClass(typeof(ViewFamilyType)) .Cast<ViewFamilyType>().First(vft => vft.ViewFamily == ViewFamily.Drafting); ViewDrafting view = ViewDrafting.Create(uidoc.Document, viewFamilyType.Id); view.ViewName = "TempDraftingView"; trans.Commit(); uidoc.ActiveView = view; } } using (Transaction trans2 = new Transaction(uidoc.Document)) { if (trans2.Start(text) == TransactionStatus.Started) { IList<Element> allViewsTemp = new FilteredElementCollector(uidoc.Document) .OfClass(typeof(View)) .ToElements(); List<ElementId> exclude = new List<ElementId>(); foreach (Element e in allViewsTemp) { View view = e as View; if (view.Name == "TempDraftingView") { exclude.Add(view.Id); } } //exclude.Add(uidoc.ActiveView.Id); ExclusionFilter filter = new ExclusionFilter(exclude); IList<Element> allViews = new FilteredElementCollector(uidoc.Document) .OfClass(typeof(View)) .WherePasses(filter) .ToElements(); // Remove all ViewTemplates, sheets, project browser and // system browser from views to be deleted List<View> viewsToDelete = new List<View>(); foreach (Element e in allViews) { View v = e as View; if (!v.IsTemplate && !(v.ViewType == ViewType.SystemBrowser) && !(v.ViewType == ViewType.DrawingSheet) && !(v.ViewType == ViewType.ProjectBrowser)) { viewsToDelete.Add(v); } } foreach (View v in viewsToDelete) { try { if (v.IsValidObject) { uidoc.Document.Delete(v.Id); } } catch (Exception ex) { TaskDialog.Show("Error", ex.Message + v.Id); } } trans2.Commit(); } } } } ////////////////////////////////////////////////////////////////////////// // // Helpers - simple delegates operating upon an instance of a door private void FlipHandAndFace(FamilyInstance e) { e.flipFacing(); e.flipHand(); } // Note: The door orientation [left/right] is according the common // conventions used by the building industry in the Czech Republic. // If the convention is different in your county (like in the U.S), // swap the code of the MakeRight and MakeLeft methods. private static void MakeLeft(FamilyInstance e) { if (e.FacingFlipped ^ e.HandFlipped) e.flipHand(); } private void MakeRight(FamilyInstance e) { if (!(e.FacingFlipped ^ e.HandFlipped)) e.flipHand(); } // Note: The In|Out orientation depends on the position of the // wall the door is in; therefore it does not necessary indicates // the door is facing Inside, or Outside, respectively. // The presented implementation is good enough to demonstrate // how to flip a door, but the actual algorithm will likely // have to be changes in a read-world application. private void TurnIn(FamilyInstance e) { if (!e.FacingFlipped) e.flipFacing(); } private void TurnOut(FamilyInstance e) { if (e.FacingFlipped) e.flipFacing(); } } // class } // namespace
It seems like for some reason I kept getting InvalidObjects into my selection and thus causing exceptions when tried to delete them. I have no idea how that is possible, but I was able to go around this by adding an "if" statement that checks for whether an object is valid right before trying to delete it.
During this process I also realized that SystemBrowser and ProjectBrowser are now a legit ViewTypes and are being returned with all views. Of course Templates have been part of that for a while now, so I also added checks to exclude all of the above from deletion list.
Also I added a quick routine to create a new Drafting view, set that to current view and exclude it from deletion. That's to prevent an error that would arise if all views were deleted from the project.
It seems to be working now. At least I am getting the results that I was expecting.
The next question is how to, instead of hitting Button1 to delete all views and Button2 to delete all sheets, set this up so i can have couple check boxes and then execute one command at the end that will either delete all views, all sheets or both sheets and views.
Can you give me some tips about that? I am guessing I should use some global variable that will be set when checkbox is checked and then when command is executed check what those variables are set to and execute the appropriate command. Any examples that I can look at?
Thanks!
// // (C) Copyright 2003-2015 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // using System; using System.Collections.Generic; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using System.Linq; namespace Revit.SDK.Samples.ModelessForm_ExternalEvent.CS { /// <summary> /// A class with methods to execute requests made by the dialog user. /// </summary> /// public class RequestHandler : IExternalEventHandler { // A trivial delegate, but handy private delegate void DoorOperation(FamilyInstance e); // The value of the latest request made by the modeless form private Request m_request = new Request(); /// <summary> /// A public property to access the current request value /// </summary> public Request Request { get { return m_request; } } /// <summary> /// A method to identify this External Event Handler /// </summary> public String GetName() { return "R2014 External Event Sample"; } /// <summary> /// The top method of the event handler. /// </summary> /// <remarks> /// This is called by Revit after the corresponding /// external event was raised (by the modeless form) /// and Revit reached the time at which it could call /// the event's handler (i.e. this object) /// </remarks> /// public void Execute(UIApplication uiapp) { try { switch (Request.Take()) { case RequestId.None: { return; // no request at this time -> we can leave immediately } case RequestId.Delete: { DeleteSheets(uiapp, "Delete sheets"); //ModifySelectedDoors(uiapp, "Delete sheets", e => e.Document.Delete(e.Id)); break; } //case RequestId.FlipLeftRight: // { // ModifySelectedDoors(uiapp, "Flip door Hand", e => e.flipHand()); // break; // } //case RequestId.FlipInOut: // { // ModifySelectedDoors(uiapp, "Flip door Facing", e => e.flipFacing()); // break; // } //case RequestId.MakeLeft: // { // ModifySelectedDoors(uiapp, "Make door Left", MakeLeft); // break; // } //case RequestId.MakeRight: // { // ModifySelectedDoors(uiapp, "Make door Right", MakeRight); // break; // } //case RequestId.TurnOut: // { // ModifySelectedDoors(uiapp, "Place door Out", TurnOut); // break; // } case RequestId.TurnIn: { DeleteViews(uiapp, "Place door In"); break; } //case RequestId.Rotate: // { // ModifySelectedDoors(uiapp, "Rotate door", FlipHandAndFace); // break; // } default: { // some kind of a warning here should // notify us about an unexpected request break; } } } finally { Application.thisApp.WakeFormUp(); } return; } /// <summary> /// The main door-modification subroutine - called from every request /// </summary> /// <remarks> /// It searches the current selection for all doors /// and if it finds any it applies the requested operation to them /// </remarks> /// <param name="uiapp">The Revit application object</param> /// <param name="text">Caption of the transaction for the operation.</param> /// private void DeleteSheets(UIApplication uiapp, String text) { UIDocument uidoc = uiapp.ActiveUIDocument; if (uidoc != null) { ICollection<ElementId> allSheets = new FilteredElementCollector(uidoc.Document) .OfClass(typeof(ViewSheet)) .ToElementIds(); using (Transaction trans = new Transaction(uidoc.Document)) { if (trans.Start(text) == TransactionStatus.Started) { foreach (ElementId id in allSheets) { uidoc.Document.Delete(id); } trans.Commit(); } } } } /// <summary> /// The main door-modification subroutine - called from every request /// </summary> /// <remarks> /// It searches the current selection for all doors /// and if it finds any it applies the requested operation to them /// </remarks> /// <param name="uiapp">The Revit application object</param> /// <param name="text">Caption of the transaction for the operation.</param> private void DeleteViews(UIApplication uiapp, String text) { UIDocument uidoc = uiapp.ActiveUIDocument; if (uidoc != null) { using (Transaction trans = new Transaction(uidoc.Document)) { if (trans.Start(text) == TransactionStatus.Started) { // create a new drafting view that will be excluded from selection // and will not be deleted. cannot delete all views from project ViewFamilyType viewFamilyType = new FilteredElementCollector(uidoc.Document) .OfClass(typeof(ViewFamilyType)) .Cast<ViewFamilyType>().First(vft => vft.ViewFamily == ViewFamily.Drafting); ViewDrafting view = ViewDrafting.Create(uidoc.Document, viewFamilyType.Id); view.ViewName = "TempDraftingView"; trans.Commit(); uidoc.ActiveView = view; } } using (Transaction trans2 = new Transaction(uidoc.Document)) { if (trans2.Start(text) == TransactionStatus.Started) { IList<Element> allViewsTemp = new FilteredElementCollector(uidoc.Document) .OfClass(typeof(View)) .ToElements(); List<ElementId> exclude = new List<ElementId>(); foreach (Element e in allViewsTemp) { View view = e as View; if (view.Name == "TempDraftingView") { exclude.Add(view.Id); } } //exclude.Add(uidoc.ActiveView.Id); ExclusionFilter filter = new ExclusionFilter(exclude); IList<Element> allViews = new FilteredElementCollector(uidoc.Document) .OfClass(typeof(View)) .WherePasses(filter) .ToElements(); // Remove all ViewTemplates, sheets, project browser and // system browser from views to be deleted List<View> viewsToDelete = new List<View>(); foreach (Element e in allViews) { View v = e as View; if (!v.IsTemplate && !(v.ViewType == ViewType.SystemBrowser) && !(v.ViewType == ViewType.DrawingSheet) && !(v.ViewType == ViewType.ProjectBrowser)) { viewsToDelete.Add(v); } } foreach (View v in viewsToDelete) { try { if (v.IsValidObject) { uidoc.Document.Delete(v.Id); } } catch (Exception ex) { TaskDialog.Show("Error", ex.Message + v.Id); } } trans2.Commit(); } } } } ////////////////////////////////////////////////////////////////////////// // // Helpers - simple delegates operating upon an instance of a door private void FlipHandAndFace(FamilyInstance e) { e.flipFacing(); e.flipHand(); } // Note: The door orientation [left/right] is according the common // conventions used by the building industry in the Czech Republic. // If the convention is different in your county (like in the U.S), // swap the code of the MakeRight and MakeLeft methods. private static void MakeLeft(FamilyInstance e) { if (e.FacingFlipped ^ e.HandFlipped) e.flipHand(); } private void MakeRight(FamilyInstance e) { if (!(e.FacingFlipped ^ e.HandFlipped)) e.flipHand(); } // Note: The In|Out orientation depends on the position of the // wall the door is in; therefore it does not necessary indicates // the door is facing Inside, or Outside, respectively. // The presented implementation is good enough to demonstrate // how to flip a door, but the actual algorithm will likely // have to be changes in a read-world application. private void TurnIn(FamilyInstance e) { if (!e.FacingFlipped) e.flipFacing(); } private void TurnOut(FamilyInstance e) { if (e.FacingFlipped) e.flipFacing(); } } // class } // namespace
It seems like for some reason I kept getting InvalidObjects into my selection and thus causing exceptions when tried to delete them. I have no idea how that is possible, but I was able to go around this by adding an "if" statement that checks for whether an object is valid right before trying to delete it.
During this process I also realized that SystemBrowser and ProjectBrowser are now a legit ViewTypes and are being returned with all views. Of course Templates have been part of that for a while now, so I also added checks to exclude all of the above from deletion list.
Also I added a quick routine to create a new Drafting view, set that to current view and exclude it from deletion. That's to prevent an error that would arise if all views were deleted from the project.
It seems to be working now. At least I am getting the results that I was expecting.
The next question is how to, instead of hitting Button1 to delete all views and Button2 to delete all sheets, set this up so i can have couple check boxes and then execute one command at the end that will either delete all views, all sheets or both sheets and views.
Can you give me some tips about that? I am guessing I should use some global variable that will be set when checkbox is checked and then when command is executed check what those variables are set to and execute the appropriate command. Any examples that I can look at?
Thanks!
Sorry, I cannot give you tips about that. It's programming 101 - you need to go back to the books.
Cheers
Sorry, I cannot give you tips about that. It's programming 101 - you need to go back to the books.
Cheers
Hahahaha, fair enough.
PS. I never studied Computer Science so sometimes those 101 tasks can be a little challanging. Anyways, thanks for help.
Hahahaha, fair enough.
PS. I never studied Computer Science so sometimes those 101 tasks can be a little challanging. Anyways, thanks for help.
I never studied Computer Science either. I have just worked my way through it. Yuu'll get there too, no doubt.
I never studied Computer Science either. I have just worked my way through it. Yuu'll get there too, no doubt.
Can't find what you're looking for? Ask the community or share your knowledge.