Hello,
I have 3 Push Buttons and Each Button will Place a Different Revit Family.
I'm still green in the API but I'm looking to build a simple Ribbon with PushButtons that place a specific family.
I have implemented my PushButtons and I can activate a command no problem. I have also built my function that takes in an XML document with a list of families and places the Detail Item using Revit's built In "PostRequestForElementTypePlacement(); which works fine on their own.
My issue, is If I have 3 buttons and want to set a Specific family to each one of those PushButtons, I don't know how to pass that variable to my function.
public Autodesk.Revit.UI.Result OnStartup(UIControlledApplication app) { // Add a new ribbon panel RibbonPanel ribbonPanel = app.CreateRibbonPanel("NewRibbonPanel"); // Setup some Default Folder Paths & Variables string thisAssemblyPath = Assembly.GetExecutingAssembly().Location; string folderPath = @"D:\Draw\Visual_Studio_Projects\RevitDetailingRibbon\RevitDetailingAddin\RevitDetailingAddin\bin\Debug"; string imagePath = @"D:\Draw\Visual_Studio_Projects\RevitDetailingRibbon\RevitDetailingAddin\RevitDetailingAddin\bin\Debug\ImageFiles"; string tab2dRebar = "Stn-2D Rebar"; string tab2dSteel = "Stn-2D Steel"; string tab2dConn = "Stn-2D Connections"; string tabSymbols = "Stn-Symbols"; string panelRebarSect = "Sect"; string panelRebarPlan = "Plan"; string panelRebarShapes = "2D Rebar Shapes"; string panelSteelSect = "Sect"; // Add a new ribbon panel app.CreateRibbonTab(tab2dRebar); RibbonPanel panelA = app.CreateRibbonPanel(tab2dRebar, panelRebarSect); RibbonPanel panelB = app.CreateRibbonPanel(tab2dRebar, panelRebarPlan); RibbonPanel panelC = app.CreateRibbonPanel(tab2dRebar, panelRebarShapes); // Standard buttons // Create a push button to trigger a command add it to the ribbon panel. PushButton btnHelloWorld = (PushButton)panelA.AddItem(new PushButtonData("cmdHelloWorld", "Hello World", thisAssemblyPath, "RevitDetailingAddin.HelloWorld")); btnHelloWorld.LargeImage = new BitmapImage(new Uri(Path.Combine(imagePath, "globe_32x32.png"), UriKind.Absolute)); btnHelloWorld.Image = new BitmapImage(new Uri(Path.Combine(imagePath, "globe_16x16.png"), UriKind.Absolute)); btnHelloWorld.ToolTipImage = new BitmapImage(new Uri(Path.Combine(imagePath, "globe_32x32.png"), UriKind.Absolute)); btnHelloWorld.ToolTip = "New Hellow World Button"; btnHelloWorld.LongDescription = "Enter the View Start Number, select views in sheet and press ESC to complete the command."; // Create a push button to trigger a command add it to the ribbon panel. PushButton btnHelloNewWorld = (PushButton)panelB.AddItem(new PushButtonData("cmdHelloNewWorld", "Hello New World", thisAssemblyPath, "RevitDetailingAddin.HelloNewWorld")); btnHelloNewWorld.LargeImage = new BitmapImage(new Uri(Path.Combine(imagePath, "globe_32x32.png"), UriKind.Absolute)); btnHelloNewWorld.Image = new BitmapImage(new Uri(Path.Combine(imagePath, "globe_16x16.png"), UriKind.Absolute)); btnHelloNewWorld.ToolTipImage = new BitmapImage(new Uri(Path.Combine(imagePath, "globe_32x32.png"), UriKind.Absolute)); btnHelloNewWorld.ToolTip = "Hellow New World Button"; btnHelloNewWorld.LongDescription = "Enter the View Start Number, select views in sheet and press ESC to complete the command."; return Result.Succeeded; }
and the code in another class to place the family for reference:
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementsnew) { // Places a Specified Detail Item (Line or Point Based) onto a View using Revits Default UI Document doc = commandData.Application.ActiveUIDocument.Document; UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; string familyName = "DC-Steel-W_Wide_Flange-Section-U-Stn"; //string familyName = "DC-Steel-W_Wide_Flange-Side-U-Stn"; string familyTypeName = "W310X39"; FamilySymbol returnValue; // Create a Function call to get the Family Name and Family Type from the XML // ========================================================================== try { // Calls familySymbolLoadedCheck to ensure Family and Type are in Project returnValue = familySymbolLoadedCheck(familyName, familyTypeName, doc, uidoc); // Uses Revits Default UI to place Detail Item uidoc.PostRequestForElementTypePlacement(returnValue); } catch { TaskDialog.Show("Revit", "Revit Family:" + Environment.NewLine + familyName + Environment.NewLine + "Revit Type:" + Environment.NewLine + familyTypeName + Environment.NewLine + "Not Found. ReLoad into Project"); // Future add code to load Load Family and Type into Project // ========================================================= return Autodesk.Revit.UI.Result.Failed; } return Autodesk.Revit.UI.Result.Succeeded; }
I have looked at a bunch of Jeremy's post like this one:
http://thebuildingcoder.typepad.com/blog/2011/02/pimp-my-autocad-or-revit-ribbon.html
But it's talking about Combo/Text box and don't have enough experience to alter it for a simple PushButton. I need examples that are really dumb down.
Any help on this would be great, I have already spent 2 weekends trying to get it going.
Matt
Solved! Go to Solution.
Solved by FAIR59. Go to Solution.
Dear Matt,
Thank you for your query and sorry that you spent two weekends struggling with it.
So, all you need now is to load the family symbol and place it in the project?
Loading an entire family is achieved by calling the LoadFamily method:
http://www.revitapidocs.com/2017/67277d5a-0ddf-b617-c9c9-911ecb928af9.htm
You can also load one single symbol from it using LoadFamilySymbol:
http://www.revitapidocs.com/2017/7c99a858-3e0e-e63b-3754-996f98d1bc2f.htm
In my use cases, I always check first whether the family (entire, or specific symbol, depending on use case) has already been loaded into the project; in that case, I can obviously skip this step.
In a second step, you place an instance. In general, this is achieved using the NewFamilyInstance method:
http://www.revitapidocs.com/2017/451ee414-cea0-e9bd-227b-c73bc93507dd.htm
The challenge here is to choose the right overload to use, depending on your family and other circumstances.
Both topics and their combination are discussed extensively with numerous examples in The Building Coder topic group on Family Instance Placement, which I just now enhanced and expanded, especially for you:
http://thebuildingcoder.typepad.com/blog/about-the-author.html#5.25.2
I hope this helps.
Best regards,
Jeremy
Dear Matt,
from your description i get the impression, that the user has no influence on the family selection.
He pushes button A and you let him place family A.
he pushes button B and you let him place family B,
he pushes button C and you let him place family C.
So the user can never select family D
Is this correct?
If so, then for every Pushbutton you call a different method.
PushButton btnHelloWorld = (PushButton)panelA.AddItem(new PushButtonData("cmdPlaceA", "family_A", thisAssemblyPath, "RevitDetailingAddin.PlaceFamilyA"));
PushButton btnHelloWorld = (PushButton)panelB.AddItem(new PushButtonData("cmdPlaceB", "family_B", thisAssemblyPath, "RevitDetailingAddin.PlaceFamilyB"));
You can use something like this:
public class PlaceFamilyA : IExternalCommand
{
public Autodesk.Revit.UI.Result Execute(ExternalCommandData revit,
ref string message, ElementSet elements)
{
PlaceFamilyFunction(FamilyA)
}
}
public class PlaceFamilyB : IExternalCommand
{
public Autodesk.Revit.UI.Result Execute(ExternalCommandData revit,
ref string message, ElementSet elements)
{
PlaceFamilyFunction(FamilyB)
}
}
Take a look at this post, I believe it might be what you are looking for: http://thebuildingcoder.typepad.com/blog/2011/02/pimp-my-autocad-or-revit-ribbon.html