C# help

I don’t know your knowledge of C#, so I go back to the basics:

C# want you to define every variable.
For example, if I need a string a double or integer the variable is:

string helloWorld = "Hello World!";
double number = 1.0;
int inTeger = 1;

When you use the Revit Api you need to do the same.
You want TitleBlocks, if you look at the revit api docs, you can see there is no specific class for titleblocks.
In this case you need to use the Element class

Let go to your public, you try to get a specific titleblock (Element) by using the familyname and the type.

Lets create a public … in this case we want a public Element, because you need an element.
To get the titleblocks we need to use the document, I will use this for my filteredelement collector.

public Element GetTitleblockByName(Document doc, string familyName, string typeName)
        {

        }

I define every input that I need in my public, doc = Document, familyName is a string, typeName is a string as well.

To retieve the elements we will use the filteredelement collector.
When we look at the revit api docs we see that the collector give a IList back when we use the .ToElements() Method:
image
FilteredElementCollector Class (revitapidocs.com)

When I return my variable tBlocks the code has an error:

That is because the public is defined as an Element, not as a IList
Now we have all titleblocks, but you want a specific tBlock. So let me change the code a little bit.

When you snoop the titleblock and check the BuiltinParameter Family Name, you see the internalDefinition = SYMBOL_FAMILY_NAME_PARAM. and this will give the value back when you use the .AsString();

So I use the collector and use the FirstOrDefault() function, inside this function a use the Lambda function. x in this case is a variable of the lambda, when x => x.get_Parameter(BuiltInParameter.SYMBOL_FAMILY_NAME_PARAM).AsString() == familyName than I get this element, but in your case you want 2 names, first the familyname and that the type name.
So I change the code in

(x => x.get_Parameter(BuiltInParameter.SYMBOL_FAMILY_NAME_PARAM).AsString() == familyName
                && x.Name == typeName);

I use the && for this.

And now you have the element:

public Element GetTitleblockByName(Document doc, string familyName, string typeName)
        {
            //FilteredElement Collector To Elements
            IList<Element> tBlocks = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_TitleBlocks).WhereElementIsElementType().ToElements();
            
            //Now we want a specific element what has the familyName and the typeName, we use the lambda for that (=>)
            Element tBlock = tBlocks.FirstOrDefault
                (x => x.get_Parameter(BuiltInParameter.SYMBOL_FAMILY_NAME_PARAM).AsString() == familyName
                && x.Name == typeName);

            return tBlock;

        }

Right now you can use this public inside your code:

image

I hope this makes sense :slight_smile:

5 Likes

Thank you, I really apreciate that. :slight_smile:

I’m going to have a really good read of that.

I’m finding learning C# 100x more difficult than Python. It’s so frustrating! Everything seems so overly complex and for Revit stuff there’s almost no information on the internet. :frowning:

2 Likes

It just a one part of Dunning–Kruger effect. When you pass it, every thing become better . Every language also have good point and bad point, we just look to it and apply for case we want.

6 Likes

Oh there is a lot of information of c# Revit API.

And there are a lot of youtube video’s for Revit :slight_smile:
I think it is important to understand the docs, when you understand this there is (almost) no limit :wink:

Goodluck!

2 Likes

When learning a new language, always start with the basics. Doesn’t matter if it’s Python, C#, Swedish, or anything else.

  • Basic vocabulary
  • Sentence structure and grammar
  • Specialized vocabulary comes next
  • And then specialized sentence structure and grammar
  • And finally functional use of the specialized vocabulary

So in the context of C#

  • Learn how various data types and what things are
  • Learn the structure of loops, classes, references, the larger solution and the like to do something unrelated (perhaps playing hangman?)
  • Learn basic implementation of the Revit API to do a simple thing that is useful in a professional context.
  • Learn how to build a full solution with the Revit API to solve a targeted business need.
3 Likes

Yeah but:

C#

namespace HelloWorld
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Hello World");
        }
    }
}

.
.
.

Python

print("Hello World!")

No wonder I’m struggling :rofl:

1 Like

Right, but C# allows a LOT more. Instead of writing to console, trigger a UI. The world of .net are at your finger tips!

1 Like

I know… I’m just moaning because it’s not easy :yum:

1 Like

hi, it’s true that it’s tempting, I tried this afternoon following an AU presentation by Mr. Graham, I find that we’re deviating quite a bit from the dynamo, we have to create bridges to be able to launch external classes, as an intellectual curiosity, it’s interesting but it requires a lot of investment (it all depends on the starting level) but dynamo and dynamo reader (it already covers almost 100% of the needs of a non-developer beginner like me ) but I salute Mr. Alien’s investment
cordially
christian.stan

1 Like

I agree, I remember a conversation between you and me about the roadmap :slight_smile:
Dynamo is a good start to understand the basics, when you use Python in Dynamo you will understand the API with his classes better, and it is nice to see every result.

In C# I had to learn to say goodbye to the “Dynamo Lists” :rofl:

1 Like