Code Reference A collection of code for my reference (and perhaps other people too)

20Aug/090

Find a child UIElement

Here is a nice little method that will find the first occurance of child UIElement.

XAML can get long and complex. This helped me find specific elements so I can set focus on them or do some other type of operation.

Call the method like this

UIElement result = FocusOnFirstElement(myLayoutRoot, typeof(Expander));

Here is the method:

/// <summary>
/// Find the first UIElement of a specific type within the specified root element.
/// UIElements in WPF have child elements under one of the following properties: Content, Child, Items, Children
/// This loops thru itself looking for any child elements.
/// </summary>
/// <param name="rootElement"></param>
/// <param name="typeToFind"></param>
/// <returns>UIElement or null if the element was not found</returns>
public UIElement FocusOnFirstElement(UIElement rootElement, Type typeToFind)
{
    bool found = false;
    UIElement currentElement = rootElement;

    var x1 = currentElement.GetType().GetProperty("Content");
    if (x1 != null)
    {
        var content = currentElement.GetType().GetProperty("Content").GetValue(currentElement, BindingFlags.GetProperty, null, null, null);

        if (content == null)
            return null;

        if (content.GetType() == typeToFind)
            return content as UIElement;

        return FocusOnFirstElement(content as UIElement, typeToFind);
    }

    var x2 = currentElement.GetType().GetProperty("Child");
    if (x2 != null)
    {
        var child = currentElement.GetType().GetProperty("Child").GetValue(currentElement, BindingFlags.GetProperty, null, null, null);

        if (child == null)
            return null;

        if (child.GetType() == typeToFind)
            return child as UIElement;

        return FocusOnFirstElement(child as UIElement, typeToFind);
    }

    var x4 = currentElement.GetType().GetProperty("Items");
    if (x4 != null)
    {
        ItemCollection items = (ItemCollection)currentElement.GetType().GetProperty("Items").GetValue(currentElement, BindingFlags.GetProperty, null, null, null);

        if (items == null)
            return null;

        foreach (var item in items)
        {
            if (item.GetType() == typeToFind)
                return item as UIElement;

            UIElement retunedElement = FocusOnFirstElement(item as UIElement, typeToFind);
            if (retunedElement != null)
                return retunedElement;
        }
    }

    var x5 = currentElement.GetType().GetProperty("Children");
    if (x5 != null)
    {
        UIElementCollection children = (UIElementCollection)currentElement.GetType().GetProperty("Children").GetValue(currentElement, BindingFlags.GetProperty, null, null, null);

        if (children == null)
            return null;

        foreach (var item in children)
        {
            if (item.GetType() == typeToFind)
                return item as UIElement;

            UIElement retunedElement = FocusOnFirstElement(item as UIElement, typeToFind);
            if (retunedElement != null)
                return retunedElement;
        }
    }

    return null;
}
30Jul/090

Getting a property from a generic object

If you have an object of an unknown type and you need a property from that object, you can easily get it using reflection.

var value = myObject.GetType().GetProperty("Id").GetValue(myObject, BindingFlags.GetProperty, null, null, null);
int id = Convert.ToInt32(value);

You must know the name of the property you need: "Id"
The object name appears twice - at the beginning and the first element of GetValue()
The BindingFlag is GetProperty because you are getting the property. duh!
The last 3 items are most often null unless your object is more complicated (indexed properties, etc)

The result is an object so you must then cast it to the required type.

If you want the property type, it is even more simple:

Type idType = myObject.GetType().GetProperty("Id").PropertyType;

Simple?

23Jul/090

Calling a generic method using reflection

Because I often forget syntax I find it useful to keep examples on my blog for reference.

  • This 1st example: Call a generic method using reflection
  • The 2nd example: Call a generic method with a return value using reflection
  • The 3rd example: Call a static generic method in another class with a return value using reflection
  • The 4th example: Call a static generic method with a return value using reflection
  • The 5th example: Calling a method with an OUT value using reflection (return value is not filled!!!!)
public void RunTest()
{
    Type type1 = typeof(string);
    Type type2 = typeof(int);

    // Example 1
    // Call a generic method using reflection
    MethodInfo m1 = this.GetType().GetMethod("Test1").MakeGenericMethod(new Type[] { type1, type2 });
    m1.Invoke(this, new object[] { "test", 11 });

    // Example 2
    // Call a generic method with a return value using reflection
    MethodInfo m2 = this.GetType().GetMethod("Test2").MakeGenericMethod(new Type[] { type1, type2 });
    string return2 = (string)m2.Invoke(this, new object[] { "test", 22 });

    // Example 3
    // Call a static generic method in another class with a return value using reflection
    MethodInfo m3 = typeof(Example3Class).GetMethod("Test3").MakeGenericMethod(new Type[] { type1, type2 });
    string return3 = (string)m3.Invoke(null, new object[] { "test", 33 });

    // Example 4
    // Call a static generic method with a return value using reflection
    MethodInfo m4 = this.GetType().GetMethod("Test4").MakeGenericMethod(new Type[] { type1, type2 });
    string return4 = (string)m4.Invoke(null, new object[] { "test", 44 });

    // Example 5
    // Calling a method with an OUT value using reflection
    // The trick here is to pass in an array of properties and access the 'out' property of the array after the call.
    // This was not possible in the previous examples because I create a new object array in the invoke call.
    string outValue = string.Empty;
    object[] parameters = new object[] { "test", 55, outValue }
    MethodInfo m5 = this.GetType().GetMethod("Test5").MakeGenericMethod(new Type[] { type1, type2 });
    string return5 = (string)m5.Invoke(this, parameters);

    // Now you can access the 'out' parameter by accessing:
    outValue = (string)parameters[2];
}

// Example 1 method
public void Test1(string x, int y)
{ }

// Example 2 method
public string Test2(string x, int y)
{
    return "return 2";
}

// Example 4 method
public static string Test4(string x, int y)
{
    return "return 4";
}

// Example 5 method
public string Test5(string x, int y, out string z)
{
    z = "out 5";
    return "return 5";
}

The class for Example 3:

public class Example3Class
{
    public Example3Class()
    {    }

    // Example 3 method
    public static string Test3(string x, int y)
    {
        return "return 3";
    }
}