XAML 滑动 CheckBox 内的图像

Image inside sliding CheckBox in XAML

我从 [这里]) 获得了以下样式,并使用 x:Name = "slider" 向边框添加了图像。我想重用这个控件,并希望能够为每个控件分配图像源,而不必为每个控件复制样式。这是我的风格:

    <Style x:Key="OrangeSwitchStyle" TargetType="{x:Type CheckBox}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <ControlTemplate.Resources>
                    <Storyboard x:Key="OnChecking">
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
                            <SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="53" />
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="OnUnchecking">
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
                            <SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="0" />
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </ControlTemplate.Resources>
                <DockPanel x:Name="dockPanel">
                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                      Content="{TemplateBinding Content}" 
                                      ContentStringFormat="{TemplateBinding ContentStringFormat}" 
                                      ContentTemplate="{TemplateBinding ContentTemplate}" 
                                      RecognizesAccessKey="True" 
                                      VerticalAlignment="Center"
                                      DockPanel.Dock="Top"/>
                    <Grid DockPanel.Dock="Bottom">
                        <Border x:Name="BackgroundBorder" 
                                BorderBrush="#FF939393" 
                                BorderThickness="1" 
                                CornerRadius="3" 
                                Height="27" 
                                Width="94">
                            <Border.Background>
                                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                    <GradientStop Color="#FFB5B5B5" Offset="0" />
                                    <GradientStop Color="#FFDEDEDE" Offset="0.1" />
                                    <GradientStop Color="#FFEEEEEE" Offset="0.5" />
                                    <GradientStop Color="#FFFAFAFA" Offset="0.5" />
                                    <GradientStop Color="#FFFEFEFE" Offset="1" />
                                </LinearGradientBrush>
                            </Border.Background>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition />
                                    <ColumnDefinition />
                                </Grid.ColumnDefinitions>
                                <Ellipse x:Name="Off" 
                                         Width="14" 
                                         Height="14" 
                                         Stroke="#FF7A7A7A" 
                                         StrokeThickness="2" 
                                         Grid.Column="1" 
                                         HorizontalAlignment="Center" 
                                         VerticalAlignment="Center" />
                                <Line x:Name="On" 
                                      X1="0" 
                                      Y1="0" 
                                      X2="0" 
                                      Y2="14" 
                                      Stroke="#FF7A7A7A" 
                                      StrokeThickness="2" 
                                      Grid.Column="0" 
                                      HorizontalAlignment="Center" 
                                      VerticalAlignment="Center" />
                            </Grid>
                        </Border>
                        <Border BorderBrush="#FF939393" 
                                HorizontalAlignment="Left"
                                x:Name="slider" 
                                Width="41" 
                                Height="27" 
                                BorderThickness="1" 
                                CornerRadius="3" 
                                RenderTransformOrigin="0.5,0.5" 
                                Margin="0">
                            <Image Source="Resources/Capture.png" Width="30" Height="30"></Image>
                            <Border.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform ScaleX="1" ScaleY="1" />
                                    <SkewTransform AngleX="0" AngleY="0" />
                                    <RotateTransform Angle="0" />
                                    <TranslateTransform X="0" Y="0" />
                                </TransformGroup>
                            </Border.RenderTransform>
                            <Border.Background>
                                <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                                    <GradientStop Color="#FFF0F0F0" Offset="0" />
                                    <GradientStop Color="#FFCDCDCD" Offset="0.1" />
                                    <GradientStop Color="#FFFBFBFB" Offset="1" />
                                </LinearGradientBrush>
                            </Border.Background>
                        </Border>
                    </Grid>
                </DockPanel>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="True">
                        <Trigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource OnUnchecking}" x:Name="OnUnchecking_BeginStoryboard" />
                        </Trigger.ExitActions>
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource OnChecking}" x:Name="OnChecking_BeginStoryboard" />
                        </Trigger.EnterActions>
                        <Setter TargetName="On" Property="Stroke" Value="White" />
                        <Setter TargetName="Off" Property="Stroke" Value="White" />
                        <!-- Change Orange or Blue color here -->
                        <Setter TargetName="BackgroundBorder" Property="Background" Value="{StaticResource CheckedOrange}" />
                        <Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="{StaticResource CheckedOrangeBorder}" />
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <!-- ToDo: Add Style for Isenabled == False -->
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

并且想要更改每个控件的源...

有什么想法吗?

谢谢!

您的问题有三种解决方案

  1. 创建继承自CheckBox控件的新Class,并把新的DependencyProperty在那里调用,例如ImageString,然后将Binding String转换为BitmapImage像这样:
 public class newCheckBox : CheckBox
    {
       // add ImageString dependency property and change it to BitmaoImage
    }

然后将您的 CheckBox 模板和图像源绑定到新 ImageString DependencyProperty.

  1. 或者你可以像这样使用 DynamicResource:
<ControlTemplate TargetType="CheckBox">
    <Border>
        <StackPanel Orientation="Horizontal">
            <Image Source="{DynamicResource ResourceKey=Img}" Height="100" Width="100" Margin="5"></Image>
            <ContentPresenter/>
        </StackPanel>
    </Border>
</ControlTemplate>

并且在定义新的 CheckBox 时使用:

<CheckBox Content="myCheckBox">
    <CheckBox.Resources>
        <ImageSource x:Key="Img">your Uri Image</ImageSource>
    </CheckBox.Resources>
</CheckBox>
  1. 3d 解决方案是创建新的 TagConverter,它采用 Tag 属性 并将其转换为 BitmapImage,如下所示:
<Style TargetType="CheckBox">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="CheckBox">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="50"></ColumnDefinition>
                        <ColumnDefinition Width="50"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Image Stretch="Fill" Source="{TemplateBinding Tag, Converter={StaticResource TagConverter}}"></Image>
                    <ContentPresenter Grid.Column="1"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

转换器代码是:

public class TagConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return new BitmapImage(new Uri(value.ToString(),UriKind.RelativeOrAbsolute));
    }
}

并将您的图片路径放入 CheckBox 标签 属性

<CheckBox Tag="1.png" Content="MyCheck 1"></CheckBox>

使用 Datatemplate 和 ContentTemplate 我们可以重用这个 style.Please 请参阅注释文本。我删除了 <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" ></ContentPresenter> 并添加了 <ContentControl ContentTemplate="{TemplateBinding ContentTemplate}" Width="30" Height="30"/> instead of Image control as image doent have ContentTemplate property.

<Window.Resources>
    <DataTemplate x:Key="Image1">
        <Image Source="darblue_tab.png"></Image>
    </DataTemplate>

    <Style TargetType="{x:Type CheckBox}">
        .......
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type CheckBox}"> 
                    ......
                    <DockPanel x:Name="dockPanel">

                        <!--Remove  ContentTemplate="{TemplateBinding ContentTemplate}" from ContentPresenter-->

                        <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" RecognizesAccessKey="True" VerticalAlignment="Center" DockPanel.Dock="Top"/>
                        <Grid DockPanel.Dock="Bottom">
                            ......
                            <Border BorderBrush="#FF939393" HorizontalAlignment="Left" x:Name="slider" Width="41" Height="27" BorderThickness="1" CornerRadius="3" RenderTransformOrigin="0.5,0.5" Margin="0">
                                <!--Use ContentControl control as image doesn't have content,ControlTemplate and ContentTemplate property.  -->
                                <ContentControl  ContentTemplate="{TemplateBinding ContentTemplate}" Width="30" Height="30"/>
                            </Border>
                            .......
                        </Grid>
                    </DockPanel>  
                    ......
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>


<CheckBox Content="Checkbox" ContentTemplate="{StaticResource Image1}" ></CheckBox>