将形状填充颜色绑定到按钮背景刷

本文关键字:按钮 背景 绑定 颜色 填充 | 更新日期: 2023-09-27 18:06:07

我想为我的应用程序创建Close/Maximize/Minimize按钮。所以我写了这段Style:

<Style x:Key="CloseButton" TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Grid Background="Transparent">
                         <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal" />
                                <VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <ColorAnimation
                                                        Storyboard.TargetName="BackgroundColor1" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)"
                                                        Duration="0"
                                                        To="#FFFF1111"/>
                                        <ColorAnimation
                                                        Storyboard.TargetName="BackgroundColor2" Storyboard.TargetProperty="(Shape.Stroke).(GradientBrush.GradientStops)[0].(GradientStop.Color)"
                                                        Duration="0"
                                                        To="#FFFF1111"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Ellipse Name="BackgroundColor1" Margin="4,0,0,0" Width="18" Height="18">
                            <Ellipse.Fill>
                                <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                                    <GradientStop Color="{StaticResource ColorBorder}" Offset="0.2"/>
                                    <GradientStop Color="WhiteSmoke" Offset=".9"/>
                                </LinearGradientBrush>
                            </Ellipse.Fill>
                        </Ellipse>
                        <Ellipse Name="BackgroundColor2" Margin="4,0,0,0" Width="18" Height="18">
                            <Ellipse.Stroke>
                                <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                                    <GradientStop Color="{StaticResource ColorBorder}" Offset="1"/>
                                    <GradientStop Color="WhiteSmoke" Offset="0"/>
                                </LinearGradientBrush>
                            </Ellipse.Stroke>
                        </Ellipse>
                        <Ellipse Margin="4,0,0,8" Width="7" Height="7">
                            <Ellipse.Fill>
                                <LinearGradientBrush StartPoint="1,0" EndPoint="0,1">
                                    <GradientStop Color="WhiteSmoke" Offset="0"/>
                                    <GradientStop Color="Transparent" Offset="0.7"/>
                                </LinearGradientBrush>
                            </Ellipse.Fill>
                        </Ellipse>
                        <Ellipse Margin="4,0,0,0" Width="18" Height="18" StrokeThickness="2" StrokeLineJoin="Round">
                            <Ellipse.Stroke>
                                <LinearGradientBrush StartPoint="1,0" EndPoint="1,1">
                                    <GradientStop Color="Black" Offset="0"/>
                                    <GradientStop Color="Transparent" Offset="1"/>
                                </LinearGradientBrush>
                            </Ellipse.Stroke>
                        </Ellipse>
                        <Ellipse Margin="4,0,0,0" Width="18" Height="18" StrokeThickness="1" StrokeLineJoin="Round">
                            <Ellipse.Stroke>
                                <LinearGradientBrush StartPoint="1,0" EndPoint="1,1">
                                    <GradientStop Color="#FF333333" Offset="1"/>
                                    <GradientStop Color="Transparent" Offset="0.5"/>
                                </LinearGradientBrush>
                            </Ellipse.Stroke>
                        </Ellipse>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

现在我有3个这个样式的副本,改变MouseOver的颜色,像这样:

<ColorAnimation Storyboard.TargetName="BackgroundColor1" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)"
<!-- Just "To" Color changes is each button -->
To="#FFFF1111"/>

但是我只想把这个颜色绑定到Button Background color,这样我就不需要有3个重复的Style。我做了一些RelativeSource绑定,但没有工作。

Q1:如何将此梯度绑定到按钮背景?
Q2:是否有其他类型的控制器可以做到这一点有颜色属性?

提前感谢。

编辑:过渡代码:

<VisualStateGroup.Transitions>
    <VisualTransition To="MouseOver" GeneratedDuration="0:0:0.2"/>
    <VisualTransition From="MouseOver" GeneratedDuration="0:0:0.2"/>
</VisualStateGroup.Transitions>

将形状填充颜色绑定到按钮背景刷

如果是我,我可能会像下面这样做,这样你就可以更容易地传递Brush, Color, ColorName等,而不是换出GradientStop,一次只处理一个对象。因为填充只接受颜色。BrushFill是不同的野兽。;)

之类的;

风格;

<Style x:Key="CloseButton2" TargetType="{x:Type Button}">
   <Setter Property="Background" Value="Red"/>
   <Setter Property="HorizontalContentAlignment" Value="Center"/>
   <Setter Property="VerticalContentAlignment" Value="Center"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type Button}">
            <Grid>
               <!-- Left this here in case you want to use it later for something. Just set Visibility. -->
               <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 
                       Background="{TemplateBinding Background}" SnapsToDevicePixels="true" Visibility="Collapsed">
                  <ContentPresenter x:Name="contentPresenter" Focusable="False"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" 
                                    RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
               </Border>
               <!-- Your new magic. -->
               <Border x:Name="buttonLight" Opacity="0"
                       Background="{TemplateBinding Background}" CornerRadius="50" 
                       Width="18" Height="18" Margin="4,0,0,0"/>

               <Ellipse Name="BackgroundColor1" Margin="4,0,0,0" Width="18" Height="18">
                  <Ellipse.Fill>
                     <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                        <GradientStop Color="Transparent" Offset="0.2"/>
                        <GradientStop Color="WhiteSmoke" Offset=".9"/>
                                    </LinearGradientBrush>
                  </Ellipse.Fill>
               </Ellipse>
               <Ellipse Name="BackgroundColor2" Margin="4,0,0,0" Width="18" Height="18">
                  <Ellipse.Stroke>
                     <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                        <GradientStop Color="Transparent" Offset="1"/>
                        <GradientStop Color="WhiteSmoke" Offset="0"/>
                                    </LinearGradientBrush>
                  </Ellipse.Stroke>
               </Ellipse>
               <Ellipse Margin="4,0,0,8" Width="7" Height="7">
                  <Ellipse.Fill>
                     <LinearGradientBrush StartPoint="1,0" EndPoint="0,1">
                        <GradientStop Color="WhiteSmoke" Offset="0"/>
                        <GradientStop Color="Transparent" Offset="0.7"/>
                                    </LinearGradientBrush>
                  </Ellipse.Fill>
               </Ellipse>
               <Ellipse Margin="4,0,0,0" Width="18" Height="18" StrokeThickness="2" StrokeLineJoin="Round">
                  <Ellipse.Stroke>
                     <LinearGradientBrush StartPoint="1,0" EndPoint="1,1">
                        <GradientStop Color="Black" Offset="0"/>
                        <GradientStop Color="Transparent" Offset="1"/>
                     </LinearGradientBrush>
                  </Ellipse.Stroke>
               </Ellipse>
               <Ellipse Margin="4,0,0,0" Width="18" Height="18" StrokeThickness="1" StrokeLineJoin="Round">
                  <Ellipse.Stroke>
                     <LinearGradientBrush StartPoint="1,0" EndPoint="1,1">
                        <GradientStop Color="#FF333333" Offset="1"/>
                        <GradientStop Color="Transparent" Offset="0.5"/>
                     </LinearGradientBrush>
                  </Ellipse.Stroke>
               </Ellipse>
            </Grid>
            <ControlTemplate.Triggers>
               <Trigger Property="IsMouseOver" Value="true">
                  <Setter Property="Opacity" TargetName="buttonLight" Value="1"/>
               </Trigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

然后,实例示例;

<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
   <Button Style="{DynamicResource CloseButton2}"/>
   <Button Background="Green" 
           Style="{DynamicResource CloseButton2}" Margin="0,10"/>
   <Button Background="Blue" 
           Style="{DynamicResource CloseButton2}"/>
</StackPanel>

希望这有帮助,干杯。

更多信息;

你仍然可以应用你的过渡,对于这个;您只需删除触发器(这部分在前一个示例中);

<!-- DELETE THIS PART -->
    <ControlTemplate.Triggers>
       <Trigger Property="IsMouseOver" Value="true">
          <Setter Property="Opacity" TargetName="buttonLight" Value="1"/>
       </Trigger>
    </ControlTemplate.Triggers>

然后把你的VisualStateManager放到Grid里面的某个地方我更喜欢在<Grid>标签的右上方;

    <!-- Invoke VisualStateManager to handle it instead of Trigger as requested. -->
    <VisualStateManager.VisualStateGroups>
       <VisualStateGroup x:Name="CommonStates">
          <VisualStateGroup.Transitions>
             <VisualTransition To="MouseOver" GeneratedDuration="0:0:0.2"/>
             <VisualTransition From="MouseOver" GeneratedDuration="0:0:0.2"/>
          </VisualStateGroup.Transitions>
          <VisualState x:Name="Normal"/>
          <VisualState x:Name="MouseOver">
             <Storyboard>
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" 
                                               Storyboard.TargetName="buttonLight"
                                               Duration="0:0:1">
                   <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                </DoubleAnimationUsingKeyFrames>
             </Storyboard>
          </VisualState>
          <VisualState x:Name="Pressed"/>
          <VisualState x:Name="Disabled"/>
       </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

…就这样,你完成了,仍然有颜色功能等:)