2013-11-14 62 views
2

簡單的語法問題。在VS2010上編程silverlight 4。我在XAML創建了一個按鈕樣式:使用樣式以編程方式創建按鈕

<UserControl.Resources> 
    <Style x:Key ="TestbuttonStyle" TargetType="Button"> 
     <Setter Property="Width" Value="150"></Setter> 
     <Setter Property="Margin" Value="0,0,0,10"></Setter> 
     <Setter Property="ContentTemplate"> 
      <Setter.Value> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Left"> 
         <Image Source="http://i40.tinypic.com/j5k1kw.jpg" Height="20" Width="20" Margin="-30,0,0,0"></Image> 
         <TextBlock Text="sampleuser&#13;sample number" Margin="5,0,0,0"></TextBlock> 
        </StackPanel> 
       </DataTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</UserControl.Resources> 

我需要建立在後面的代碼的按鈕,但使用這種風格。我試過這樣的東西:

 Button btn = new Button(); 
     //btn.Style = {TestbuttonStyle}; -what do i put here? 
     grid.children.add(btn); 

如何應用樣式並添加到我的usercontrol網格?

回答

5

最初我以爲你在使用WPF。然後我意識到這是關於Silverlight,它沒有類似於WPF的FindResource或TryFindResource的分層資源查找幫助器方法。

然而,在互聯網上快速搜索放棄this article描述了一個很好的擴展方法,你可以使用:

public static object TryFindResource(this FrameworkElement element, object resourceKey) 
{ 
    var currentElement = element; 

    while (currentElement != null) 
    { 
     var resource = currentElement.Resources[resourceKey]; 
     if (resource != null) 
     { 
      return resource; 
     } 

     currentElement = currentElement.Parent as FrameworkElement; 
    } 

    return Application.Current.Resources[resourceKey]; 
} 

然後你可以使用它像這樣:

btn.Style = (Style)this.TryFindResource("TestbuttonStyle"); 
0

十分感謝這麼很多,你找到的那篇文章正是我想要的。我現在有一個稍微複雜一些的問題 - 我如何在.cs代碼後面的數據模板中更改我的文本塊的文本?

我知道這個問題已經被問數千次 - 一個文章,我讀的是這樣的:http://social.msdn.microsoft.com/Forums/silverlight/en-US/8c20cd79-b667-41db-958d-a0691a8c3188/accessing-controls-inside-a-datatemplate-from-codebehind?forum=silverlightwinphone

所以,我實現了自己的功能:

 public static T FindName<T>(string name, DependencyObject reference) where T : FrameworkElement 
    { 
     return FindNameInternal<T>(name, reference); 
    } 

    private static IEnumerable<DependencyObject> GetChildren(DependencyObject reference) { int childCount = VisualTreeHelper.GetChildrenCount(reference); for (int i = 0; i < childCount; i++) { yield return VisualTreeHelper.GetChild(reference, i); } } 

    private static T FindNameInternal<T>(string name, DependencyObject reference) where T : FrameworkElement 
    { 
     foreach (DependencyObject obj in GetChildren(reference)) 
     { 
      T elem = obj as T; 
      if (elem != null && elem.Name == name) 
      { 
       return elem; 
      } 
      elem = FindNameInternal<T>(name, obj); 
      if (elem != null) 
      { 
       return elem; 
      } 
      else 
      { 
       if (obj.GetType().FullName == "System.Windows.Controls.DataField") 
        elem = (obj as DataField).Content as T; 

       if (elem != null && elem.Name == name) 
        return elem; 
      } 
     } 
     return null; 
    } 

我命名的DataTemplate「TB1」在我的文字塊(我想這兩個名稱和X:名稱),但是當我嘗試:

var tb1 = FindName<TextBlock>("tb1", this); 
     tb1.Text = "hi"; 

它拋出一個空指針異常(因爲TB1爲空)。直接編輯數據模板內的文本塊的最簡單方法是什麼?

非常感謝您的幫助!

0

有一個頓悟,並能對其進行編輯thruough裝載的事件,並使用發件人:

xaml: <DataTemplate x:Name="dtt"> 
        <StackPanel Loaded="skloaded" .... 

c#: public void skloaded(object sender, RoutedEventArgs e) 
     { 
     StackPanel stap = sender as StackPanel; 
     TextBlock txb = stap.FindName("tb1") as TextBlock; 
     txb.Text = "hello world!"; 

     } 

不過,這就意味着我只能加載過程中對其進行編輯(這是確定我的項目現在) ,所以我仍然會喜歡更強大的解決方案!