Placing a family symbol and setting it's parameters

Placing a family symbol and setting it's parameters

Khadourwaseem
Enthusiast Enthusiast
4,294 Views
12 Replies
Message 1 of 13

Placing a family symbol and setting it's parameters

Khadourwaseem
Enthusiast
Enthusiast

So I have this issue, when I place my Generic annotation I can't find a way to set its parameters, I have a generic annotation family created and I want a way to assign set its parameters after or before placing, but I can't find a way to do it, and am sure that someone has figured it out before so if you can be helpful and guide me to an example I would appreciate it. thanks 

this is the code I used to locate the family and place it 

IList<Element> Floordetails = col.OfClass(typeof(FamilySymbol)).WhereElementIsElementType().ToElements();
FamilySymbol floordetail = null;
foreach (Element f in Floordetails)
{
if (f.Name == "_VA_Floor_detail")
{
floordetail = f as FamilySymbol;
break;
}
}
uidoc.PostRequestForElementTypePlacement(floordetail);

0 Likes
Accepted solutions (2)
4,295 Views
12 Replies
Replies (12)
Message 2 of 13

joshua.lumley
Advocate
Advocate

Change parameters with a 'set' like myElement.GetParameters("Comment")[0].Set("Hello World"); ....but first you need the ID in order to get myElement. This post from the bulding coder tells you how to do it.

https://thebuildingcoder.typepad.com/blog/2010/06/place-family-instance.html 

Message 3 of 13

Khadourwaseem
Enthusiast
Enthusiast

Am I missing something? int n is 1. I know that there is an ElementId in this list yet when I try to access it and set its parameters the error message is : "Object reference not set to an instance of an object." param was bull

_addedd_element_ids.Clear();
app.DocumentChanged += new EventHandler<DocumentChangedEventArgs>(OnDocumentChanged);
using (Transaction tr = new Transaction(doc))
{
	tr.Start("Placing the element");
	FamilyInstance s = doc.Create.NewFamilyInstance(diffuserPnt, floordetail, doc.ActiveView);
	tr.Commit();
}
app.DocumentChanged -= new EventHandler<DocumentChangedEventArgs>(OnDocumentChanged);
int n = _addedd_element_ids.Count;
using (Transaction tr2 = new Transaction(doc))
{
tr2.Start("Setting the new value");

	ElementId Eid = _addedd_element_ids[0];
	Element Ele = doc.GetElement(Eid);
	Parameter param = Ele.LookupParameter("T_1");
	param.Set("Hello");

tr2.Commit();
}

 

0 Likes
Message 4 of 13

jeremy_tammik
Alumni
Alumni

Here is a sample showing how to pick up the recently placed family instance after placement:

 

https://thebuildingcoder.typepad.com/blog/2010/06/place-family-instance.html

 

Here are pointers to more PostRequestForElementTypePlacement samples:

 

https://thebuildingcoder.typepad.com/blog/2015/03/postrequestforelementtypeplacement.html

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 5 of 13

jeremy_tammik
Alumni
Alumni

Use RevitLookup to explore your BIM and ensure that the element really has the parameter T_1 that you are trying to set.

 

From your description, it apparently has not.

 

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 6 of 13

Khadourwaseem
Enthusiast
Enthusiast

It's not a buildInparameter, I created the family myself. and there is such a parameter and currently its set to "hello", tho when I try to get the element by element id maybe something went wrong from the error message  "Object reference not set to an instance of an object.". and I can't seem to find it 
and the examples you pointed out is only for retrieving the count of the added elements in the transaction, not picking it 

0 Likes
Message 7 of 13

joshua.lumley
Advocate
Advocate
Accepted solution

It is possible to test part of your code (isolate the issue) by getting the element directly from id with Element myElement = doc.GetElement(new ElementID(12345));  The element ID of existing elements can be found using the ID of Selection button on the Manage tab.

 

Element myElement = doc.GetElement(new ElementID(12345));  

 

0 Likes
Message 8 of 13

RPTHOMAS108
Mentor
Mentor

You seem to be adding an event handler for DocumentChanged to capture something added to the model.

 

Why are you not updating the parameters of 'FamilyInstance s' directly (it is why Create.NewFamilyInstance returns it)?

 

Nobody can help because nobody knows the things you do i.e. where _addedd_element_ids comes from, the parameters within your family and where they are located i.e. on the Type or Instance?

 

Note that often .GetAddedElementIds will contain many things for one item added i.e. when you create floor you get sketch and sketch lines and floor instance, not just floor. So not a good idea to index it without knowing what is in it (or assuming you know). If user copy/pastes elements you'll get a type and an instance if the type doesn't exist. In your case you are probably safe but why the need to do it this way?

 

 

0 Likes
Message 9 of 13

Khadourwaseem
Enthusiast
Enthusiast
It worked!!!!!! thank you so much, the code is in a mess, once I clean it up I'll post it here, may one day, it helps another newbie just like me
0 Likes
Message 10 of 13

Khadourwaseem
Enthusiast
Enthusiast
I want my code to do two things: create a family symbol and modify its parameters, I honestly don't know another way of capturing something I just created, I used this:https://thebuildingcoder.typepad.com/blog/2010/06/place-family-instance.html to capture a recently created elementID and then set its parameters.
and it WORKED!!! I'll be posting the full code here in a few days, for may it will be useful for someone like me,
0 Likes
Message 11 of 13

joshua.lumley
Advocate
Advocate

Good work. 

0 Likes
Message 12 of 13

RPTHOMAS108
Mentor
Mentor
Accepted solution

The link was regarding PromptForFamilyInstancePlacement and I can understand the reason for looking for database changes with that since it is a UI method.

 

However you mixed that with:

FamilyInstance s = doc.Create.NewFamilyInstance(diffuserPnt, floordetail, doc.ActiveView);

 

In that 's' is what you get so you don't have to find it in a list of ElementIds.

 

Family.FamilyPlacementType tells you what to do in terms of placement, I would tend to favour that along with method indicated red above. PromptForFamilyInstancePlacement is good for doing very basic things, you can extend those things or use other ways available.

Message 13 of 13

Khadourwaseem
Enthusiast
Enthusiast

You're absolutely right, I had no idea I could do that 

UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Application app = uiapp.Application;
            Document doc = uidoc.Document;

            

            // The filter to find what type of family we want to place 

            FilteredElementCollector col = new FilteredElementCollector(doc);
            IList<Element> Floordetails = col.OfClass(typeof(FamilySymbol)).WhereElementIsElementType().ToElements();
            FamilySymbol floordetail = null;
            foreach (Element f in Floordetails)
            {
                if (f.Name == "_VA_Floor_detail")
                {
                    floordetail = f as FamilySymbol;
                    break;
                }
            }

            // Prompts the user to pick a point to place the family 
            XYZ diffuserPnt = uidoc.Selection.PickPoint("Pick Text Origin");

            using (Transaction tr = new Transaction(doc))
            {
                tr.Start("Placing a floor detail");
                FamilyInstance s = doc.Create.NewFamilyInstance(diffuserPnt, floordetail, doc.ActiveView);
// The parameter should be an instance parameter and NOT a type parameter for this method to work
                Parameter f = s.LookupParameter("_VA_Leader_length");
// Divide by 304.8 as i change the unit from feet to mm
                f.Set(160 / 304.8);
                tr.Commit();
            }
   

Here is what I ended up with. Thank you everybody for helping me