2013-10-16 22 views
3

我有一個包含多個TabItems的WPF應用程序。每個TabItem都是不同的,有一個文本和一個圖標。WPF - 創建具有變量/參數的可重複使用樣式

這是TabItem's風格是如何定義的:

<TabItem.Style> 
        <Style TargetType="TabItem"> 
         <Setter Property="Header"> 
          <Setter.Value> 
           <StackPanel Orientation="Horizontal"> 
            <Image Margin="10,0,0,0" Height="40" Width="40" Source="Images/IconLeafGrey.png"/> 
            <TextBlock Text="This is the heading" VerticalAlignment="Center" Style="{StaticResource Heading2}" Margin="10,0,0,0"/> 
           </StackPanel> 
          </Setter.Value> 
         </Setter> 
         <Setter Property="Template"> 
          <Setter.Value> 
           <ControlTemplate TargetType="{x:Type TabItem}"> 
            <Grid> 
             <Border Name="Border" BorderBrush="Black" BorderThickness="1,1,1,1" CornerRadius="6,6,0,0" > 
              <Border.Background> 
               <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> 
                <GradientStop Color="#f5f7f8" Offset="0.0" /> 
                <GradientStop Color="#c5d0dd" Offset="1.0" /> 
               </LinearGradientBrush> 
              </Border.Background> 
              <ContentPresenter Name="ContentSite" VerticalAlignment="Center" HorizontalAlignment="Left" ContentSource="Header" Margin="5,2,0,2"/> 
             </Border> 
            </Grid> 
            <ControlTemplate.Triggers> 
             <Trigger Property="IsSelected" Value="True"> 
              <Setter Property="Background" TargetName="Border"> 
               <Setter.Value> 
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> 
                 <LinearGradientBrush.GradientStops> 
                  <GradientStop Color="#ebedee" Offset="0.0" /> 
                  <GradientStop Color="#88a2bd" Offset="1.0" /> 
                 </LinearGradientBrush.GradientStops> 
                </LinearGradientBrush> 
               </Setter.Value> 
              </Setter> 
             </Trigger> 
            </ControlTemplate.Triggers> 
           </ControlTemplate> 
          </Setter.Value> 
         </Setter> 
         <Style.Triggers> 
          <Trigger Property="IsSelected" Value="True"> 
           <Setter Property="Header"> 
            <Setter.Value> 
             <StackPanel Orientation="Horizontal"> 
              <Image Margin="10,0,0,0" Height="40" Width="40" Source="Images/IconLeaf.png"/> 
              <TextBlock Text="This is the heading" VerticalAlignment="Center" Style="{StaticResource Heading2}" Margin="10,0,0,0"/> 
             </StackPanel> 
            </Setter.Value> 
           </Setter> 

          </Trigger> 
         </Style.Triggers> 
        </Style> 
       </TabItem.Style> 

因此,而不是寫爲每個TabItem的這個XAML標記的,我想在我的ResourceDictionary定義一次這種風格,但與圖標Text屬性作爲可選參數。所以,後來我可以定義一個TabItem的是這樣的:

<TabItem Width="250" Height="60" Style="{StaticResource CustomTabItem}" > 

從來就閱讀它不是直接可能的風格接受這樣的參數,但它應該是更多鈔票用某種結合。我沒有發現究竟如何,所以我真的希望你能幫助。

親切的問候。

+0

您可以創建樣式[根據](http://msdn.microsoft.com/en-us/library/sy stem.windows.style.basedon.aspx)只覆蓋Icon和Text屬性的主要樣式。 –

回答

2

一個做這將是,如果你有固定的TabItems號碼,你不想上的TabControl產生TabItems通過ItemsSourceBinding的方式。然後在你的TabItem.Style可以使用Resource鍵來得到這樣的文本和源代碼:

<StackPanel Orientation="Horizontal"> 
     <Image Margin="10,0,0,0" Height="40" Width="40" Source="{DynamicResource Image1}"/> 
     <TextBlock Text="{DynamicResource Header}" VerticalAlignment="Center" Style="{StaticResource Heading2}" Margin="10,0,0,0"/> 
    </StackPanel> 

,併爲您的TabItems您可以定義這些資源:

 <TabItem Width="250" Height="60" Style="{StaticResource CustomTabItem}"> 
     <TabItem.Resources> 
       <System:String x:Key="Header">TabItem1</System:String> 
       <System:String x:Key="Image1">image/1.png</System:String> 
       <System:String x:Key="Image2">image/2.png</System:String> 
      </TabItem.Resources> 
     </TabItem> 
     <TabItem Width="250" Height="60" Style="{StaticResource CustomTabItem}"> 
     <TabItem.Resources> 
       <System:String x:Key="Header">TabItem2</System:String> 
       <System:String x:Key="Image1">image/3.png</System:String> 
       <System:String x:Key="Image2">image/4.png</System:String> 
      </TabItem.Resources> 
     </TabItem> 

你也將需要更新您的Style到設置的HeaderTemplate代替Header

 <Style x:Key="CustomTabItem" TargetType="TabItem"> 
     <Setter Property="HeaderTemplate"> 
      <Setter.Value> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <Image x:Name="HeaderImage" Margin="10,0,0,0" Height="40" Width="40" Source="Images/IconLeafGrey.png"/> 
         <TextBlock Text="{DynamicResource Header}" VerticalAlignment="Center" Margin="10,0,0,0"/> 
        </StackPanel> 
        <DataTemplate.Triggers> 
         <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type TabItem}}}" Value="true"> 
          <Setter TargetName="HeaderImage" Property="Source" Value="Images/IconLeaf.png"/> 
         </DataTrigger> 
        </DataTemplate.Triggers> 
       </DataTemplate> 

      </Setter.Value> 
     </Setter> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type TabItem}"> 
        <Grid> 
         <Border Name="Border" BorderBrush="Black" BorderThickness="1,1,1,1" CornerRadius="6,6,0,0" > 
          <Border.Background> 
           <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> 
            <GradientStop Color="#f5f7f8" Offset="0.0" /> 
            <GradientStop Color="#c5d0dd" Offset="1.0" /> 
           </LinearGradientBrush> 
          </Border.Background> 
          <ContentPresenter Name="ContentSite" VerticalAlignment="Center" HorizontalAlignment="Left" ContentSource="Header" Margin="5,2,0,2"/> 
         </Border> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsSelected" Value="True"> 
          <Setter Property="Background" TargetName="Border"> 
           <Setter.Value> 
            <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> 
             <LinearGradientBrush.GradientStops> 
              <GradientStop Color="#ebedee" Offset="0.0" /> 
              <GradientStop Color="#88a2bd" Offset="1.0" /> 
             </LinearGradientBrush.GradientStops> 
            </LinearGradientBrush> 
           </Setter.Value> 
          </Setter> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
+0

非常感謝,它似乎在工作...差不多! 問題是,當我在兩個或多個TabItem上設置樣式時,Visual Studio會警告我「指定的元素已經是另一個元素的邏輯子元素,請先斷開它」。如果我運行應用程序失敗,'設置屬性'System.Windows.FrameworkElement.Style'拋出一個異常。' 我擺弄它,如果我從樣式中刪除整個Header部分,錯誤消失...任何想法? – Farsen

+0

你能分享你如何定義資源? – Nitin

+0

我現在已經更新了我如何定義資源的問題。不知道這是否是這樣做的,但評論不能支持這麼多角色? – Farsen

2

你只需要設置TabItem.DataContext到包含您的TextBlockImage控制值的對象:

在代碼:

public class TabItemData 
{ 
    public string ImageSource { get; set; } 
    public string Heading { get; set; } 
} 

在你Style在XAML:

<StackPanel Orientation="Horizontal"> 
    <Image Margin="10,0,0,0" Height="40" Width="40" Source="{Binding ImageSource}"/> 
    <TextBlock Text="{Binding Heading}" VerticalAlignment="Center" 
     Style="{StaticResource Heading2}" Margin="10,0,0,0"/> 
</StackPanel> 

在您查看的型號中:

public class TabControlViewModel 
{ 
    public TabControlViewModel() 
    { 
     TabItemData = new TabItemData() { Header = "Some header", 
      ImageSource = "Images/IconLeafGrey.png" }; 
    } 

    public TabItemData TabItemData { get; set; } 
} 

在XAML:

<TabItem DataContext="{Binding TabItemData}"> 
    ... 
</TabItem> 

當然,我已經離開了數據對象和INotifyPropertyChanged界面,你應該實現一些初始化,但我希望你的想法。