I'm writing an Addin for Revit with the template of Jeremy Tammik, which creates me a Ribbon with Buttons.
I'm reading in an excel file, selecting lines and a starting point.
My Ribbon
My WinForm
After the User is finished with his input, he should click on a "Done" button (which is missing in my case^^) and it should generate some FamilyInstances in the Project without closing the WinForm.
My Problems:
- I can't use
ShowDialog()
right? Because this will create me a modal form and then i can't get any user input since the Revit Window is greyed out - I can't use
Show()
right? Since my Code will just continue
My Question:
Can someone maybe help me to find the right approach for my problem. I'm not quite sure if my approach is even going to work at the end
What i've tried so far:
I tried to make a Transaction in the WinForm Class but i knew this wasn't going to work.
I'm thinking about a separate class which will save the user input and a second ExternalCommand Class which will execute the Transaction to create the FamilyInstances.
I looked into the SDK and found the ModelessForm_ExternalEvent but i was hard for me to understand it...
I also found these posts and tried to understand them:
https://forums.autodesk.com/t5/revit-api-forum/winform-focus-after-user-selection/td-p/7344224
Revit Pick element from WinForm
My Code:
I have an App Class which creates the Ribbon and Buttons:
class App : IExternalApplication
{
public Result OnStartup(UIControlledApplication a)
{
// Ingenieurbau Reiter erstellen
string engineerTabName = "Ingenieurbau Addin";
a.CreateRibbonTab(engineerTabName);
// Gruppen erstellen
RibbonPanel lswPanel = a.CreateRibbonPanel(engineerTabName, "Lärmschutzwand");
// Buttons hinzufügen
AddLswPushButtons(lswPanel);
AddTestPushButton(lswPanel);
return Result.Succeeded;
}
private void AddLswPushButtons(RibbonPanel panel)
{
// Strings erzeugen
string lswName1 = "LSW Daten einlesen";
string lswAssemblyName1 = Assembly.GetExecutingAssembly().Location;
string lswClassName1 = "IngenieurbauAddin1.Lsw.DataInput";
// ButtonData erzeugen
PushButtonData lswPushButtonData1 = new PushButtonData(lswName1, lswName1, lswAssemblyName1, lswClassName1);
// ButtonData dem Panel hinzufügen und in einen PushButton umwandeln
PushButton lswPushButton1 = panel.AddItem(lswPushButtonData1) as PushButton;
// ButtonBild einfügen
lswPushButton1.LargeImage = PngImageSource("IngenieurbauAddin1.Resources.Excel.png");
}
}
I have a DataInput Class which shows the Form:
[Transaction(TransactionMode.Manual)]
class DataInput : IExternalCommand
{
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;
// Form instanziieren
DataInputForm dataInputForm = new DataInputForm(uidoc);
// Form starten
dataInputForm.Show();
return Result.Succeeded;
}
}
And this is my DataInputForm Class (i know that the PlaceFamily
doesn't work):
public partial class DataInputForm : System.Windows.Forms.Form
{
private UIDocument UIDocument { get; set; }
private Document Document { get; set; }
public DataInputForm(UIDocument uiDocument)
{
UIDocument = uiDocument;
Document = uiDocument.Document;
InitializeComponent();
}
private void btnSelectPoint_Click(object sender, EventArgs e)
{
Hide();
SelectionHelper selectionHelper = new SelectionHelper(Document);
XYZ point = selectionHelper.SelectLineEndPoint(UIDocument);
labelPointLocalXValue.Text = Math.Round(point.X, 3).ToString();
labelPointLocalYValue.Text = Math.Round(point.Y, 3).ToString();
labelPointLocalZValue.Text = Math.Round(point.Z, 3).ToString();
Show();
PlaceFamily(point);
}
private void PlaceFamily(XYZ point)
{
FamilySymbolHelper familySymbolHelper = new FamilySymbolHelper(Document);
FamilyInstanceHelper familyInstanceHelper = new FamilyInstanceHelper(Document);
FamilySymbol famSym = familySymbolHelper.FamilySymbolByName("Master-Bauteil");
try
{
using (Transaction t = new Transaction(Document, "Familie platzieren"))
{
t.Start();
FamilyInstance famInst = familyInstanceHelper.FamilyInstanceByPoint(famSym, point);
t.Commit();
}
}
catch (Exception e)
{
TaskDialog.Show("Error", e.Message);
}
}
}
I just want to enter the inputs (Excelfile, Lines, Point) and then it should generate me the FamilyInstances. But i'm kinda stuck now ^^.
I appreciate any help.