WPF - 使用变量/参数创建可重用样式



我有一个包含多个TabItems的WPF应用程序。每个 TabItem 彼此不同,具有文本和图标。

以下是

定义 TabItem 样式的方式:

<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 标记,而是想在我的资源字典中定义一次此样式,但将 Icon 和 Text 属性作为可选参数。所以我之后可以像这样定义一个 TabItem :

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

我读过,样式不可能直接接受这样的参数,但它应该是可以通过某种绑定来实现的。我还没有确切地知道如何,所以我真的希望你能提供帮助。

亲切问候。

一种方法是,如果您有固定数量的TabItems并且不想通过 TabControl 上的ItemsSource Binding生成TabItems。然后在您的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>

对于选项卡项,您可以定义以下资源:

     <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>
您只需

要将TabItem.DataContext设置为包含TextBlockImage控件值的对象:

在代码中:

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

在 XAML 中的Style中:

<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接口,但我希望你明白这个想法。

相关内容

  • 没有找到相关文章

最新更新