void OnDocumentChanged( object sender, DocumentChangedEventArgs e) { ICollection <ElementId> idsAdded = e.GetAddedElementIds(); int n = idsAdded.Count; Debug.Print("{0} id{1} added.", n, Util.PluralSuffix(n)); // This does not work, because the handler will // be called each time a new instance is added, // overwriting the previous ones recorded: //_added_element_ids = e.GetAddedElementIds(); _added_element_ids.AddRange(idsAdded); if (_place_one_single_instance_then_abort && 0 < n) { // Why do we send the WM_KEYDOWN message twice? // I tried sending it once only, and that does // not work. Maybe the proper thing to do would // be something like the Press.OneKey method... // //Press.OneKey( _revit_window.Handle, // (char) Keys.Escape ); // // Nope, that did not work. // // Answer: When you place instances with // PromptForFamilyInstancePlacement, the previous // one remains selected just until you drop the // next one. The first esc key hit removes that // selection while still allowing you to continue // adding instances to the model. Only a second // esc hit aborts the command. //Press.PostMessage( _revit_window.Handle, // (uint) Press.KEYBOARD_MSG.WM_KEYDOWN, // (uint) Keys.Escape, 0 ); // 2018 //Press.PostMessage( _revit_window.Handle, // (uint) Press.KEYBOARD_MSG.WM_KEYDOWN, // (uint) Keys.Escape, 0 ); // 2018 Press.PostMessage(_revit_window, (uint)Press.KEYBOARD_MSG.WM_KEYDOWN, (uint)Keys.Escape, 0); // 2019 Press.PostMessage(_revit_window, (uint)Press.KEYBOARD_MSG.WM_KEYDOWN, (uint)Keys.Escape, 0); // 2019 } }
/// <summary> /// Here is a part or our code to start a Revit command. /// The aim of the code is to set a wall type current in the Revit property window. /// We only start up the wall command with the API and let the user do the drawing of the wall. /// This solution can also be used to launch other Revit commands. /// </summary> public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; // name of target wall type that we want to use: string wallTypeName = "Generic - 203"; WallType wallType = GetFirstWallTypeNamed( doc, wallTypeName); Wall wall = GetFirstWallUsingType( doc, wallType); // select the wall in the UI uidoc.Selection.Elements.Add(wall); if (0 == uidoc.Selection.Elements.Size) { // no wall with the correct wall type found FilteredElementCollector collector = new FilteredElementCollector(doc); Level ll = collector .OfClass(typeof(Level)) .FirstElement() as Level; // place a new wall with the // correct wall type in the project //Line geomLine = app.Create.NewLineBound( XYZ.Zero, new XYZ( 2, 0, 0 ) ); // 2013 Line geomLine = Line.CreateBound(XYZ.Zero, new XYZ(2, 0, 0)); // 2014 Transaction t = new Transaction( doc, "Create dummy wall"); t.Start(); //Wall nw = doc.Create.NewWall( geomLine, // 2012 // wallType, ll, 1, 0, false, false ); Wall nw = Wall.Create(doc, geomLine, // 2013 wallType.Id, ll.Id, 1, 0, false, false); t.Commit(); // Select the new wall in the project uidoc.Selection.Elements.Add(nw); // Start command create similar. In the // property menu, our wall type is set current Press.Keys("CS"); // select the new wall in the project, // so we can delete it uidoc.Selection.Elements.Add(nw); // erase the selected wall (remark: // doc.delete(nw) may not be used, // this command will undo) Press.Keys("DE"); // start up wall command Press.Keys("WA"); } else { // the correct wall is already selected: Press.Keys("CS"); // start "create similar" } return(Result.Succeeded); }