0

我試圖從後面的代碼檢索Application.Resources元素,我很困惑,因爲通過擴展方法這樣做似乎不工作另一方面,使完全相同的方法成爲「正常」的方法成功。通過擴展方法檢索Silverlight 4 XAML定義的靜態資源不按預期方式工作

讓我指出這幾乎完全是針對Silverlight開發中的自我訓練。

我想要實現的是通過代碼隱藏從XAML中檢索Style(定義爲資源)的通用TextBlock

這是(它裏面App.xaml定義)

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

正如你所看到的財產,這是一個簡單的「畫我的文字塊白色」屬性。

這裏的一個「正常」的方法:

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; 
      } 
... 

這是一個擴展方法的形式的代碼:

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; 
    } 
... 

這是上述方法(注意,這是一個呼叫者不同類,但都住在同一個命名空間):

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); 
    } 
... 

我認爲代碼很簡單,其目的是不言自明的。

請注意,擴展方法方法有什麼問題? 瀏覽谷歌和SO本身,在我看來這兩種方法應該工作。

我錯過了什麼?

回答

1

當我發現關於這個問題更多的研究後,我想要做的(拿起任何東西,把它放在任何地方)不能通過擴展方法完成,因爲如果它是一個值類型(他們提供的功能範例傾向於不變性,或者我被告知),它們不會更改「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; 
     } 
1

試試這個

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"); 
+0

Upvoted,因爲它的工作原理,謝謝。無論如何,我正在使用更通用的方法,以便能夠在任何地方應用任何東西,只要傳遞屬性的名稱(我正在考慮控制模板,樣式等)。如果在短時間內沒有其他事情發生,我們會接受這個答案。 – Alex 2012-03-08 09:28:13

+0

你是對的alex你可以使用擴展方法替換這個對象。你需要做的是使用父對象來應用擴展參數,這樣你可以給子屬性賦值。 – 2012-03-08 12:12:41