I create a user control which call class. The class contain code for joining wall and column. While running the show error that Starting a transaction from an external application running outside of API context is not allowed.
After solving this error it show the error Object reference not set to an instance of an object. How can I solved this error and run my code?
This is my code:
USER CONTROL CLASS:
namespace AdvanceQuickJoin
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl
{
ExternalCommandData commandData;
UIApplication app;
public UserControl1(ExternalCommandData commandDatax)
{
commandData = commandDatax;
InitializeComponent();
// Set a fixed height and width for the control.
}
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello friends! I am from the WPF world!");
}
private void button_Click(object sender, RoutedEventArgs e)
{
// MessageBox.Show("");
WallStcolumnJoin wc = new WallStcolumnJoin();
wc.Execute(app);
}
}
}
This is my class which has code for joining:
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
namespace AdvanceQuickJoin
{
[Transaction(TransactionMode.Manual)]
class WallStcolumnJoin :IExternalEventHandler
{
public void Execute(UIApplication app)
{
UIDocument uidoc = app.ActiveUIDocument;
Document doc = uidoc.Document;
using (Transaction t = new Transaction(doc, "Join All Walls/Column"))
{
t.Start();
FilteredElementCollector column = new FilteredElementCollector(doc, doc.ActiveView.Id);
column.OfClass(typeof(FamilyInstance));
column.OfCategory(BuiltInCategory.OST_StructuralColumns);
foreach (FamilyInstance c in column)
{
FilteredElementCollector Walls = new FilteredElementCollector(doc, doc.ActiveView.Id);
Walls.OfClass(typeof(Wall));
Walls.WherePasses(new ElementIntersectsElementFilter(c));
foreach (Wall w in Walls)
{
JoinGeometryUtils.JoinGeometry(doc, w, c);
}
}
t.Commit();
}
}
}
}
Solved! Go to Solution.
Solved by jeremytammik. Go to Solution.
This topic has now been discussed hundreds of times.
Here are some pointers to previous answers:
http://thebuildingcoder.typepad.com/blog/about-the-author.html#5.28
I tried it but I get this error
And If I clicked on Yes button then revit has been closed. After opening that recovery file it shows that wall column has been joined. If I want to ignore this error and changes has been made in that file itself and don't want to close the revit . What change should I do?
It get solution that if I change the lines win.Show(); to win.ShowDialog(); then I get result it successfully executed. Why this is happining? I want to use form and revit at a time. win.show give me to work both but when I use win.ShowDialog() it open the form but while form is open I am not able to use Revit.
I want that I use win.show() method and didn't want to give that previous error.
The Revit API cannot be used at all outside a valid Revit API context.
A valid Revit API context is provided inside Revit event handlers and nowhere else.
Using Show displays a modeless dialogue, which has no valid Revit API context.
One way to get one is to use an external event.
Please read the material I pointed to and all will be clear.
The Revit SDK sample on modeless events demonstrates how to proceed.
Cheers,
Jeremy
Thank you Jeremy!!
I done with the modeless form. I had one problem when I pass string from form to the request handler class it show blank value.
In my Form I passed String to the Request handler class at button click event
private void button1_Click(object sender, EventArgs e)
{
string selected = this.comboBox1.GetItemText(this.comboBox1.SelectedItem);
RequestHandler req = new RequestHandler();
req.run(selected);
}
Request Handler class:
public class RequestHandler
{
string lvl;
public void run(string selected1)
{
lvl = selected1;
}
public void Execute(UIApplication uiapp, RequestId reqest)
{
switch (reqest)
{
case RequestId.None:
{
return; // no request at this time -> we can leave immediately
}
case RequestId.level:
{
level(uiapp,lvl);
break;
}
}
}
public void level(UIApplication uiapp,string lvl1)
{
string levelcheck = lvl1;
TaskDialog.Show("Revit", "level==" + levelcheck);// It shows blank while at run method it shows correct value which I selected from drop down list.
}
}
Make string lvl static.
public class RequestHandler
{
static string lvl;
public void run(string selected1)
{
lvl = selected1;
}
}
Don't miss the update on this topic here:
http://thebuildingcoder.typepad.com/blog/2017/05/external-access-to-the-revit-api.html
Cheers,
Jeremy
Can't find what you're looking for? Ask the community or share your knowledge.