我想创建自定义进度条样式,从底部显示图像填充。 我创建了两个图片,背景:
和前景:
想法是创造这样的东西:
Inside Blend我创造了这种风格:
<Style x:Key="ImageFill" TargetType="{x:Type ProgressBar}">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid x:Name="TemplateRoot" SnapsToDevicePixels="true">
<Image x:Name="PART_Track" Source="Play_Background.png" Margin="1" Stretch="Fill"/>
<Rectangle x:Name="PART_Indicator" Margin="1" HorizontalAlignment="Left" Fill="#FFD6931C">
<Rectangle.OpacityMask>
<RadialGradientBrush>
<GradientStop Color="Black" Offset="0.87"/>
<GradientStop Color="Transparent" Offset="0.87"/>
</RadialGradientBrush>
</Rectangle.OpacityMask>
</Rectangle>
<Image Source="Play_Foreground.png" Margin="1" Stretch="Fill"/>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
但是当设定值为60时,我得到了这个:
我可以将OpacitMmask更改为:
<RadialGradientBrush Center="106,104" GradientOrigin="60,60" MappingMode="Absolute" RadiusY="97" RadiusX="98">
<GradientStop Color="Black" Offset="0.87"/>
<GradientStop Color="Transparent" Offset="0.87"/>
</RadialGradientBrush>
但是当我调整进度条的大小时,我会得到不必要的行为:
如何解决这个问题?我需要掩码将MappingMode设置为RelativeToBoundingBox,这样我就可以设置不同的大小到进度条。
以下是我在Blend中生成的完整XAML:
<Window x:Class="ImageProgressBar.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="389" Width="523">
<Window.Resources>
<Style x:Key="ImageFill" TargetType="{x:Type ProgressBar}">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid x:Name="TemplateRoot" SnapsToDevicePixels="true">
<Image x:Name="PART_Track" Source="Play_Background.png" Margin="1" Stretch="Fill"/>
<Rectangle x:Name="PART_Indicator" Margin="1" HorizontalAlignment="Left" Fill="#FFD6931C">
<Rectangle.OpacityMask>
<RadialGradientBrush Center="106,104" GradientOrigin="60,60" MappingMode="Absolute" RadiusY="97" RadiusX="98">
<GradientStop Color="Black" Offset="0.87"/>
<GradientStop Color="Transparent" Offset="0.87"/>
</RadialGradientBrush>
</Rectangle.OpacityMask>
</Rectangle>
<Image Source="Play_Foreground.png" Margin="1" Stretch="Fill"/>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ProgressBar
Maximum="{Binding ElementName=MySlider, Path=Maximum, Mode=TwoWay}" Minimum="{Binding ElementName=MySlider, Path=Minimum, Mode=TwoWay}" Value="{Binding ElementName=MySlider, Path=Value, Mode=TwoWay}"
HorizontalAlignment="Left" Height="200" Margin="10,10,0,0" VerticalAlignment="Top" Width="200" Style="{DynamicResource ImageFill}"/>
<ProgressBar
Maximum="{Binding ElementName=MySlider, Path=Maximum, Mode=TwoWay}" Minimum="{Binding ElementName=MySlider, Path=Minimum, Mode=TwoWay}" Value="{Binding ElementName=MySlider, Path=Value, Mode=TwoWay}"
HorizontalAlignment="Left" Height="100" Margin="294,10,0,0" VerticalAlignment="Top" Width="100" Style="{DynamicResource ImageFill}"/>
<Slider Name="MySlider" HorizontalAlignment="Left" Margin="10,215,0,0" VerticalAlignment="Top" Width="200" Minimum="0" Maximum="100" Value="0"/>
</Grid>
</Window>
我找到了http://vbcity.com/blogs/xtab/archive/2009/11/24/wpf-controltemplates-creating-a-non-rectangular-progressbar.aspx,但不能在我的风格中使用它。
答案 0 :(得分:5)
我设法创造了我想要的效果。 以下是它的外观:
及以下是使用样式和滑块的工作代码来更改进度条的值:
<?xml version="1.0" encoding="UTF-8"?>
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="ImageProgressBar.MainWindow" Title="ProgressBar Image Fill" Height="284" Width="598" Background="#FFEAE0E0">
<Window.Resources>
<Style x:Key="ImageFill" TargetType="{x:Type ProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid x:Name="TemplateRoot" SnapsToDevicePixels="true">
<Image x:Name="PART_Track" Source="Play_Background.png" Margin="1" Stretch="Fill" />
<Rectangle x:Name="PART_Indicator" Margin="1" HorizontalAlignment="Left" Fill="{TemplateBinding Foreground}">
<Rectangle.OpacityMask>
<RadialGradientBrush Center="106,104" GradientOrigin="60,60" MappingMode="Absolute" RadiusY="97" RadiusX="98">
<GradientStop Color="Black" Offset="0.87" />
<GradientStop Color="Transparent" Offset="0.87" />
</RadialGradientBrush>
</Rectangle.OpacityMask>
</Rectangle>
<Image Source="Play_Foreground.png" Margin="1" Stretch="Fill" />
</Grid>
<ControlTemplate.Triggers>
<!-- Getting vertical style working using technique described here: http://stackoverflow.com/a/6849237/7532 -->
<Trigger Property="Orientation" Value="Vertical">
<Setter TargetName="PART_Indicator" Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="270" />
</Setter.Value>
</Setter>
<Setter TargetName="PART_Indicator" Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}" />
<Setter TargetName="PART_Indicator" Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}" />
<Setter TargetName="PART_Indicator" Property="VerticalAlignment" Value="Bottom" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SimpleImageFill" TargetType="{x:Type ProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid x:Name="TemplateRoot" SnapsToDevicePixels="true">
<Image x:Name="PART_Track" Source="Play_Game_Empty.png" />
<Canvas ClipToBounds="True" x:Name="PART_Indicator" HorizontalAlignment="Left">
<Image x:Name="Image_Fill" Source="Play_Game_Fill.png"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}" />
</Canvas>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Orientation" Value="Vertical">
<Setter TargetName="PART_Indicator" Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="270" />
</Setter.Value>
</Setter>
<Setter TargetName="Image_Fill" Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="-270" />
</Setter.Value>
</Setter>
<Setter TargetName="PART_Indicator" Property="Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}" />
<Setter TargetName="PART_Indicator" Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}" />
<Setter TargetName="PART_Indicator" Property="VerticalAlignment" Value="Bottom" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ProgressBar Foreground="Orange" Orientation="Vertical" Maximum="{Binding ElementName=MySlider, Path=Maximum, Mode=TwoWay}" Minimum="{Binding ElementName=MySlider, Path=Minimum, Mode=TwoWay}" Value="{Binding ElementName=MySlider, Path=Value, Mode=TwoWay}" HorizontalAlignment="Left" Height="200" Margin="10,10,0,0" VerticalAlignment="Top" Width="200" Style="{DynamicResource ImageFill}" />
<ProgressBar Maximum="{Binding ElementName=MySlider, Path=Maximum, Mode=TwoWay}" Minimum="{Binding ElementName=MySlider, Path=Minimum, Mode=TwoWay}" Value="{Binding ElementName=MySlider, Path=Value, Mode=TwoWay}" HorizontalAlignment="Left" Height="200" Margin="227.5,10,0,0" VerticalAlignment="Top" Width="200" Style="{DynamicResource ImageFill}" />
<Slider Name="MySlider" HorizontalAlignment="Left" Margin="10,215,0,0" VerticalAlignment="Top" Width="200" Minimum="0" Maximum="100" Value="0" />
<ProgressBar Orientation="Vertical" Maximum="{Binding ElementName=MySlider, Path=Maximum, Mode=TwoWay}" Minimum="{Binding ElementName=MySlider, Path=Minimum, Mode=TwoWay}" Value="{Binding ElementName=MySlider, Path=Value, Mode=TwoWay}" HorizontalAlignment="Left" Height="150" Margin="432.5,10,0,0" VerticalAlignment="Top" Width="150" Style="{DynamicResource SimpleImageFill}" />
</Grid>
</Window>
我实际上创造了两种风格:
答案 1 :(得分:0)
检查出来WPF: Anchor points don't work well sometimes问题是你的大小和边距绝对不是你控件的大小。