Search code examples
c#silverlightdata-bindingextension-methodsstaticresource

Retrieve Silverlight 4 XAML-defined static resource through extension method not working as expected


I'm trying to retrieve an Application.Resources element from code behind and I'm puzzled since doing so via an extension method doesn't seem to work, on the other hand making the exact same method a "normal" one succeeds.

Let me point out this is almost exclusively aimed at self-training in Silverlight development.

What I want to achieve is to retrieve the Style (defined as resource) for a generic TextBlock from XAML through code-behind.

This is the property (it's defined inside App.xaml)

<Application.Resources>
    <Style x:Key="contentTextStyle" TargetType="TextBlock">
        <Setter Property="Foreground" Value="White" />
    </Style>
    [...]

As you can see, it's a simple "paint my textblock white" property.

Here's a "normal" method:

public static class ApplicationResources
{
 public static T RetrieveStaticResource<T>(string resourceKey) where T : class
            {
                if(Application.Current.Resources.Contains(resourceKey))
                    return Application.Current.Resources[resourceKey] as T;
                else
                    return null;
            }
...

This is the code in the form of an extension method:

public static class ApplicationResources
{
public static void RetrieveStaticResourceExt<T>(this T obj, string resourceKey) where T : class
    {
        if(Application.Current.Resources.Contains(resourceKey))
            obj = Application.Current.Resources[resourceKey] as T;
        else
            obj = null;
    }
...

This is the caller for the methods above (note this is a different class, but both live in the same namespace):

public static class UIElementsGenerator
{
/// <summary>
/// Appends a TextBlock to 'container', name and text can be provided (they should be, if this is used more than once...)
/// </summary>
public static void AddTextBlock(this StackPanel container, string controlName = "newTextBlock", string text = "")
    {
        TextBlock ret = new TextBlock();
        ret.Text = controlName + ": " + text;
        ret.TextWrapping = TextWrapping.Wrap;

        //This uses the 1st non-extension method, this **WORKS** (textblock turns out white)
        ret.Style = MyHelper.RetrieveStaticResource<Style>("contentTextStyle");

        //This uses the 2nd one, and **DOESN'T WORK** (textbox stays black)
        ret.Style.RetrieveStaticResourceExt<Style>("contentTextStyle");

        container.Children.Add(ret);
    }
...

I think code is simple enough in its purpose to be self-explanatory.

Getting to the point, what's wrong with the extension method approach ? Browsing through google and SO itself, it seems to me both methods should work.

What am I missing ?


Solution

  • As I found out after more research on the subject, what I want to do (pick up anything and put it anywhere) cannot be done via extension methods, since they won't change the "this" parameter if it's a value type (the functional paradigm they provide leans toward immutability, or so I've been told).

    Here's what I came up with, looks like I won't get any closer:

    public static T GetStaticResource<T>(string resourceKey) where T : class
            {
                if (Application.Current.Resources.Contains(resourceKey))
                    return Application.Current.Resources[resourceKey] as T;
                else
                    return null;
            }