首页 文章

在ControlTemplate DataTrigger中更改按钮背景

提问于
浏览
0

我想为"color swatch"按钮定义一个WPF ControlTemplate . 基本上,我希望能够使用这样的模板:

<Button Template="{StaticResource SwatchButtonTemplate}" Background="{Binding ActiveColor}">

ActiveColor 是数据上下文中的 Color 属性 . 我已经用这个模板实现了这个目标:

<ControlTemplate x:Key="SwatchButtonTemplate" TargetType="{x:Type Button}">
    <Border Name="OuterBorder" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{StaticResource BorderBrush}" Background="{TemplateBinding Background}">
        <Border Name="InnerBorder" BorderThickness="0" BorderBrush="White" Background="{TemplateBinding Background}">
            <ContentPresenter/>
        </Border>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter TargetName="OuterBorder" Property="BorderThickness" Value="1"/>
            <Setter TargetName="InnerBorder" Property="BorderThickness" Value="1"/>
            <Setter TargetName="OuterBorder" Property="BorderBrush" Value="{StaticResource MouseOverAccentBrush}"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

但是现在我想做的是如果颜色是透明的,则使用特殊的刷子作为按钮背景(例如,如果颜色是透明的,则在背景中显示红色的“X”) .

我似乎无法弄清楚如何在模板中设置检查背景颜色的触发器,如果它是透明的,请为Background属性使用不同的画笔 . 我已经尝试将DataTrigger添加到模板中:

<ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            ...
        </Trigger>
        <DataTrigger Binding="{TemplateBinding Background}" Value="#00000000">
            <Setter TargetName="InnerBorder" Property="Background" Value="{StaticResource transparent_swatch_brush}"/>
        </DataTrigger>
    </ControlTemplate.Triggers>

但是在使用它时我得到了一个XamlParseException .

编辑:此模板的完整用法位于样本按钮列表中,列表的源绑定到 ObservableCollection<Brush> ,名为 ColorList ,填充 SolidColorBrushes (其中一个是透明的)

<ItemsControl ItemsSource="{Binding ColorList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button x:Name="button" Background="{Binding}"
                    Template="{StaticResource SwatchButtonTemplate}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Height="20" Rows="1" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

以及完整的模板定义:

<ControlTemplate x:Key="SwatchButtonTemplate" TargetType="{x:Type Button}">
    <Border Name="OuterBorder" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{StaticResource BorderBrush}" Background="{TemplateBinding Background}">
        <Border Name="InnerBorder" BorderThickness="0" BorderBrush="White" Background="{TemplateBinding Background}">
            <ContentPresenter/>
        </Border>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter TargetName="OuterBorder" Property="BorderThickness" Value="1"/>
            <Setter TargetName="InnerBorder" Property="BorderThickness" Value="1"/>
            <Setter TargetName="OuterBorder" Property="BorderBrush" Value="{StaticResource MouseOverAccentBrush}"/>
        </Trigger>
        <DataTrigger Binding="{Binding Background, RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="#00ffffff">
            <Setter TargetName="InnerBorder" Property="Background" Value="{StaticResource transparent_swatch_brush}"/>
        </DataTrigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

2 回答

  • 0

    感谢@EdPlunkett建议避免在数据触发器中使用“” . 解决方案(仅限XAML)是使用“Self”相关源:

    <ControlTemplate x:Key="SwatchButtonTemplate" TargetType="{x:Type Button}">
        <Border Name="OuterBorder" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{StaticResource BorderBrush}" Background="{TemplateBinding Background}">
            <Border Name="InnerBorder" BorderThickness="0" BorderBrush="White" Background="{TemplateBinding Background}">
                <ContentPresenter/>
            </Border>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter TargetName="InnerBorder" Property="BorderThickness" Value="1" />
            </Trigger>
            <DataTrigger Binding="{Binding Path=Background.Color, RelativeSource={RelativeSource Self}}" Value="#00ffffff">
                <Setter TargetName="InnerBorder" Property="Background" Value="{StaticResource transparent_swatch_brush}" />
            </DataTrigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    

    (另请注意,Colors.Transparent是#00ffffff,而不是我认为的#00000000) .

  • 0

    你可以通过绑定到 Button 类型的anchestor来修复它,如下所示:

    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            ...
        </Trigger>
        <DataTrigger Binding="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}" Value="#00000000">
            <Setter TargetName="InnerBorder" Property="Background" Value="{StaticResource transparent_swatch_brush}"/>
        </DataTrigger>
    

    这将使用 Button 中的 Background 属性

相关问题