Place FamilyInstance in Revit, Autodesk.Revit.Exceptions.InvalidOperationException

Place FamilyInstance in Revit, Autodesk.Revit.Exceptions.InvalidOperationException

jw.vanasselt
Advocate Advocate
416 Views
3 Replies
Message 1 of 4

Place FamilyInstance in Revit, Autodesk.Revit.Exceptions.InvalidOperationException

jw.vanasselt
Advocate
Advocate

Hi all,


I see alot of forums and blogs about this issue.

 

I try to understand why my script doesn't work and give the error:

Autodesk.Revit.Exceptions.InvalidOperationException: 'Starting a transaction from an external application running outside of API context is not allowed.'

 

Input:

private void Selecteer_Click(object sender, RoutedEventArgs e)
        {
            //Selecteer button actief maken
            Selecteer.IsEnabled= true;

            //Types ophalen voor selectie, fittingen zijn elementen
            Type[] elementtypes = { typeof(Pipe), typeof(Element), typeof(Duct) };
            //Te gebruiken parameter of de naam in te zoeken            
            BuiltInParameter param = BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM;
            //VDS selection filter, naam van family/type contains dyka dan in filter toevoegen
            //param is de te zoeken builtin parameter
            ISelectionFilter filter = new VDS_SelectionFilter("dyka", elementtypes, param);

            try
            {
                //Reference maken van de selectie
                Reference[] references = (Reference[])uidoc.Selection.PickObjects(ObjectType.Element, filter, "Selecteer dyka artikelen").ToArray();
                foreach (Reference reference in references)
                {
                    //Elementen ophalen vanuit reference
                    Element selectedElement = doc.GetElement(reference.ElementId);

                    //Elementen toevoegen in lijst om te gebruiken in andere private void.
                    geselecteerdeElementen.Add(selectedElement);                             
                }
            }
            catch(Exception)
            {
                TaskDialog.Show("Error", "er zijn geen elementen geselecteerd.");

                Result res  = Result.Failed;
            }
        }

 

Code with transaction:

        private void Voltooien_Click(object sender, RoutedEventArgs e)
        {

            // Gebruik de lijst van geselecteerde elementen hier
            var elementGroups = geselecteerdeElementen.GroupBy(element => element.LookupParameter("prefabnummer").AsString());

            List<XYZ> points = new List<XYZ>();


            // Loop door elke groep en geef de elementen in de groep weer
            foreach (var group in elementGroups)
            {
                // neem het eerste element in de groep
                var firstElement = group.First();


                if (firstElement.Category.Name.Contains("Fittings")) // als het een fitting is
                {
                    // haal de locatie van de fitting op
                    var location = (firstElement.Location as LocationPoint).Point;

                    // gebruik de locatie om een Point aan te maken
                    var point = new XYZ(location.X, location.Y, location.Z);
                    points.Add(point);

                    // doe iets met de Point
                    Debug.Print($"Fitting location: {point}");
                }
                else if (firstElement.Category.Name == "Pipes" || firstElement.Category.Name == "Ducts") // als het een buis/duct is
                {
                    // haal de locatie van het hart van de buis op
                    var location = (firstElement.Location as LocationCurve).Curve.Evaluate(0.5, true);

                    // gebruik de locatie om een Point aan te maken
                    var point = new XYZ(location.X, location.Y, location.Z);
                    points.Add(point);

                    // doe iets met de Point
                    Debug.Print($"Buis hart: {point}");

                }

            }

            FilteredElementCollector collector = new FilteredElementCollector(doc);
            FamilySymbol symbol = collector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_GenericModel)
                .FirstOrDefault(x => x.Name == "00_GM_UN_prefabnummer") as FamilySymbol;

            using (Transaction tx = new Transaction(doc, "VDS_Prefabnummerblok plaatsen"))
            {
                try
                {
                    tx.Start();

                    for (int i = 0; i < points.Count; i++)
                    {
                        FamilyInstance fi = doc.Create.NewFamilyInstance(points[i], symbol, StructuralType.NonStructural);
                    }

                    tx.Commit();

                }
                catch (Exception ex)
                {
                    tx.RollBack();
                }
            }

            Close(); 
        }

 Why is this outside the Revit Api and how can I fix it?


KG,

Jan Willem

Accepted solutions (1)
417 Views
3 Replies
Replies (3)
Message 2 of 4

RPTHOMAS108
Mentor
Mentor
Accepted solution

You need a valid context to interact with Revit.

 

If this is modeless form then the context goes out of scope as soon as the window is finished showing.

 

Refer to SDK samples namely:

...\Samples\ModelessDialog\ModelessForm_ExternalEvent

Message 3 of 4

jw.vanasselt
Advocate
Advocate

I tried but can't get it work.

Is there a solution for example?

 

Tried to use the example of the sdk but i tried to understand how it works

0 Likes
Message 4 of 4

jw.vanasselt
Advocate
Advocate

Over here the files.

0 Likes