WPF-使用变量/参数创建可重用样式
我有一个WPF应用程序,它包含几个选项卡项。每个选项卡项都不同,有一个文本和一个图标 以下是TabItem样式的定义方式:WPF-使用变量/参数创建可重用样式,wpf,styles,Wpf,Styles,我有一个WPF应用程序,它包含几个选项卡项。每个选项卡项都不同,有一个文本和一个图标 以下是TabItem样式的定义方式: <TabItem.Style> <Style TargetType="TabItem"> <Setter Property="Header"> <Setter.Value>
<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中定义一次这个样式,但将Icon和Text属性作为可选参数。之后我可以定义一个TabItem,如下所示:
<TabItem Width="250" Height="60" Style="{StaticResource CustomTabItem}" >
我已经读到,样式不可能直接接受这样的参数,但它应该可以通过某种绑定实现。不过我还没有弄清楚具体的方法,所以我真的希望你能帮我
问候。您只需将
选项卡项.DataContext
设置为包含文本块
和图像
控件值的对象:
代码:
public class TabItemData
{
public string ImageSource { get; set; }
public string Heading { get; set; }
}
在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>
在XAML中:
<TabItem DataContext="{Binding TabItemData}">
...
</TabItem>
...
当然,我省略了一些数据对象的初始化和您应该实现的INotifyPropertyChanged接口,但我希望您能理解。一种方法是,如果您有固定数量的
选项卡项
,并且不希望通过选项卡控件上的项源
绑定
生成选项卡项
。然后在选项卡item.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>
您可以创建只覆盖图标和文本属性的主样式。非常感谢,它似乎正在工作。。。几乎!问题是,当我在两个或多个选项卡项上设置样式时,VisualStudio会警告我“指定的元素已经是另一个元素的逻辑子元素。请先断开它的连接”。如果我运行应用程序,它会失败,因为'Set property'System.Windows.FrameworkElement.Style'抛出了一个异常。我处理了它,如果我从样式中删除整个标题部分,错误就会消失。。。有什么想法吗?你能分享一下你是如何定义资源的吗?我现在更新了我如何定义资源的问题。不知道这是不是一种方法,但是注释不能支持这么多字符?实际上我想知道您是如何定义TabItem的。参考资料。。。您已将代码两次添加到TabItem StyleAh抱歉。这就是我如何定义TabItem:TabItem1的
<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 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>