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>
并且想要更改每个控件的源...
有什么想法吗?
谢谢!
您的问题有三种解决方案
- 创建继承自
CheckBox
控件的新Class,并把新的DependencyProperty
在那里调用,例如ImageString
,然后将Binding String转换为BitmapImage
像这样:
public class newCheckBox : CheckBox
{
// add ImageString dependency property and change it to BitmaoImage
}
然后将您的 CheckBox
模板和图像源绑定到新 ImageString
DependencyProperty
.
- 或者你可以像这样使用 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>
- 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>
我从 [这里]) 获得了以下样式,并使用 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>
并且想要更改每个控件的源...
有什么想法吗?
谢谢!
您的问题有三种解决方案
- 创建继承自
CheckBox
控件的新Class,并把新的DependencyProperty
在那里调用,例如ImageString
,然后将Binding String转换为BitmapImage
像这样:
public class newCheckBox : CheckBox { // add ImageString dependency property and change it to BitmaoImage }
然后将您的 CheckBox
模板和图像源绑定到新 ImageString
DependencyProperty
.
- 或者你可以像这样使用 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>
- 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>