C# 通过扩展方法检索Silverlight 4 XAML定义的静态资源未按预期工作

C# 通过扩展方法检索Silverlight 4 XAML定义的静态资源未按预期工作,c#,silverlight,data-binding,extension-methods,staticresource,C#,Silverlight,Data Binding,Extension Methods,Staticresource,我试图从代码隐藏中检索Application.Resources元素,我感到困惑,因为通过扩展方法这样做似乎不起作用,另一方面,使完全相同的方法成为“正常”方法 让我指出,这几乎完全是为了在Silverlight开发中进行自我培训 我想要实现的是通过代码隐藏从XAML检索通用TextBlock的样式(定义为资源) 这是属性(它在App.xaml中定义) [...] 如您所见,这是一个简单的“将我的文本块绘制为白色”属性 这里有一个“正常”方法: public static class App

我试图从代码隐藏中检索Application.Resources元素,我感到困惑,因为通过扩展方法这样做似乎不起作用,另一方面,使完全相同的方法成为“正常”方法

让我指出,这几乎完全是为了在Silverlight开发中进行自我培训

我想要实现的是通过代码隐藏从XAML检索通用
TextBlock
样式(定义为资源)

这是属性(它在
App.xaml
中定义)


[...]
如您所见,这是一个简单的“将我的文本块绘制为白色”属性

这里有一个“正常”方法:

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;
            }
...
公共静态类应用程序资源
{
公共静态T RetrieveStaticResource(字符串resourceKey),其中T:class
{
if(Application.Current.Resources.Contains(resourceKey))
将Application.Current.Resources[resourceKey]返回为T;
其他的
返回null;
}
...
这是扩展方法形式的代码:

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;
    }
...
公共静态类应用程序资源
{
公共静态void retrieveStaticResourceText(此T对象,字符串resourceKey),其中T:class
{
if(Application.Current.Resources.Contains(resourceKey))
obj=应用程序.Current.Resources[resourceKey]作为T;
其他的
obj=null;
}
...
这是上述方法的调用方(请注意,这是一个不同的类,但两者位于同一命名空间中):

公共静态类UIElementsGenerator
{
/// 
///将TextBlock附加到“容器”中,可以提供名称和文本(如果多次使用,则应提供这些名称和文本…)
/// 
公共静态void AddTextBlock(此StackPanel容器,string controlName=“newTextBlock”,string text=”“)
{
TextBlock ret=新的TextBlock();
ret.Text=controlName+“:”+Text;
ret.TextWrapping=TextWrapping.Wrap;
//这使用第一种非扩展方法,该**工作**(文本块变为白色)
ret.Style=MyHelper.RetrieveStaticResource(“contentTextStyle”);
//这使用第二个,并且**不起作用**(文本框保持黑色)
ret.Style.retrieveStaticResourceText(“contentTextStyle”);
容器.Children.Add(ret);
}
...
我认为代码的目的非常简单,可以自我解释

说到点子上,扩展方法有什么问题? 在我看来,浏览谷歌和谷歌本身,这两种方法都应该有效

我错过了什么?

试试这个

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

在对这个主题进行了更多的研究之后,我发现,我想做的事情(拿起任何东西放在任何地方)不能通过扩展方法来完成,因为如果“this”参数是值类型(它们提供的函数范式倾向于不变性,或者我被告知如此),它们不会改变

这是我想到的,看起来我不会再靠近了:

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;
        }
publicstatict GetStaticResource(stringresourcekey),其中T:class
{
if(Application.Current.Resources.Contains(resourceKey))
将Application.Current.Resources[resourceKey]返回为T;
其他的
返回null;
}

Upvoted,因为它很有效,谢谢。无论如何,我想要一种更通用的方法,以便能够在任何地方应用任何东西,只要传递属性的名称(我想是controltemplates、styles等)。如果在短时间内没有出现任何其他问题,将接受此答案。您是对的,alex您可以使用扩展方法替换此对象。您需要做的是使用父对象应用扩展参数,这样您可以为子属性指定一些值。
 public static void ApplyStyleResourceExt<T>(this T obj, string resourceKey) where T : FrameworkElement
        {
            if (Application.Current.Resources.Contains(resourceKey))
                obj.Style  = Application.Current.Resources[resourceKey] as Style;
            else
                obj.Style = null;
        }
ret.ApplyStyleResourceExt("contentTextStyle");
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;
        }