在XAML中滑动CheckBox内部的图像

时间:2015-01-18 20:57:23

标签: wpf xaml wpf-controls

我从[Here] https://stackoverflow.com/a/5349484/3260977获得了以下样式,并且我在边框上添加了一个图像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>

想要更改每个控件的来源......

有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

您的问题有三种解决方案

  1. 创建继承自CheckBox Control的新类,并将新DependencyProperty调用为例如ImageString,然后将绑定字符串转换为BitmapImage,如下所示:
  2.  public class newCheckBox : CheckBox
        {
           // add ImageString dependency property and change it to BitmaoImage
        }
    

    然后放置CheckBox模板并将图片来源绑定到新的ImageString DependencyProperty

    1. 或者您可以像这样使用DynamicResource:
    2. <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,如下所示:
      2. <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>
        

答案 1 :(得分:1)

使用Datatemplate和ContentTemplate,我们可以重用此样式。请参阅注释文本。我已移除 <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>