在Silverlight中,我想显示上传过程的进度,作为图像上的一系列增量颜色填充。
例如,
这是进度为0时:
这是30%:
和100%是完全彩色的图像:
如何控制颜色填充(我知道这将借助于技巧,如覆盖原始图像的最终图像)来显示进度?
我的任务可能很棘手,因为该图像是Windows Phone项目中按钮的OpacityMask。
P.S。只是为了避免混淆,因为我担心问题的设计方面。通过某些操作挂钩进度的逻辑已经到位。我只需要列出一个进展的介绍。
答案 0 :(得分:2)
修改强>
我做了一个实现。 A more thorough explanation and download of the code can be found on my blog
C#:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace CustomControls
{
[TemplatePart(Name="CLIPRECTANGLE", Type=typeof(RectangleGeometry))]
public class ImageProgressBar : ProgressBar
{
public ImageProgressBar()
{
this.DefaultStyleKey = typeof(ImageProgressBar);
}
public ImageSource Source
{
get { return (ImageSource)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(ImageSource), typeof(ImageProgressBar), new PropertyMetadata(null));
public Brush Fill
{
get { return (Brush)GetValue(FillProperty); }
set { SetValue(FillProperty, value); }
}
public static readonly DependencyProperty FillProperty =
DependencyProperty.Register("Fill", typeof(Brush), typeof(ImageProgressBar), new PropertyMetadata(null));
private RectangleGeometry _clip;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_clip = this.GetTemplateChild("CLIPRECTANGLE") as RectangleGeometry;
this.ValueChanged += ImageProgressBar_ValueChanged;
this.SizeChanged += ImageProgressBar_SizeChanged;
}
void ImageProgressBar_SizeChanged(object sender, SizeChangedEventArgs e)
{
UpdateClip();
}
void ImageProgressBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
UpdateClip();
}
private void UpdateClip()
{
if (_clip != null)
{
_clip.Rect = new Rect(0, 0, this.ActualWidth, this.ActualHeight * ((this.Value - this.Minimum) / (this.Maximum - this.Minimum)));
}
}
}
}
模板:generic.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomControls">
<Style TargetType="local:ImageProgressBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ImageProgressBar">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Margin="{TemplateBinding Margin}"
Background="{TemplateBinding Background}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<Grid>
<Image Source="{TemplateBinding Source}"
Stretch="Fill" />
<Rectangle Fill="{TemplateBinding Fill}">
<Rectangle.OpacityMask>
<ImageBrush ImageSource="{Binding Path=Source, RelativeSource={RelativeSource TemplatedParent}}"
Stretch="Fill" />
</Rectangle.OpacityMask>
<Rectangle.Clip>
<RectangleGeometry x:Name="CLIPRECTANGLE" />
</Rectangle.Clip>
</Rectangle>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
使用方法:
<my:ImageProgressBar Width="100"
Height="100"
Fill="Red"
Source="ProgressBar.png"
Minimum="100"
Maximum="200"
Value="{Binding ElementName=slider1, Path=Value, Mode=TwoWay}" />
<Slider Margin="0"
Name="slider1"
VerticalAlignment="Top"
Minimum="100"
Maximum="200"
Value="125" />
像魅力一样:
原始答案
你可以像这样创建一个线性渐变画笔:
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="Black" Offset="1"/>
<GradientStop Color="Lime" Offset="1"/>
<GradientStop Color="Lime" Offset="1"/>
</LinearGradientBrush>
使用此画笔绘制形状/字符/文本/任何内容。
要显示进度,只需更新中间两个渐变停止的偏移。您可以绑定这些以使其更容易。
创建一个真正的进度条:为ProgressBar创建一个模板,并(多个)将偏移量绑定到进度条的值,最小值和最大值,并按(Value - Minimum)/(Maximum - Minimum)
计算偏移量
使用位图(PNG):
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center">
<Image Source="ProgressBar.png"
Width="100"
Height="100" />
<Rectangle Fill="Lime">
<Rectangle.OpacityMask>
<ImageBrush ImageSource="ProgressBar.png" />
</Rectangle.OpacityMask>
<Rectangle.Clip>
<RectangleGeometry Rect="0,25,100,75"/>
</Rectangle.Clip>
</Rectangle>
</Grid>
进度更改时替换Rect。切断正确的金额。
请注意,相同的图像用于蒙版。
答案 1 :(得分:0)
我前几天制作了自定义ProgressBar。我不打算告诉你如何做你的(因为我不是设计师),但它并不困难。
<ControlTemplate x:Key="CustomProgressBarTemplate" TargetType="ProgressBar">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Determinate"/>
<VisualState x:Name="Indeterminate">
<!--Modyify your Storyboard-->
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="IndeterminateGradientFill"
Storyboard.TargetProperty="(Shape.Fill).(LinearGradientBrush.Transform).(TransformGroup.Children)[0].X"
Duration="00:00:.5" From="0" To="20" />
<ObjectAnimationUsingKeyFrames Duration="00:00:00" Storyboard.TargetName="IndeterminateRoot" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Duration="00:00:00" Storyboard.TargetName="DeterminateRoot" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!--Default Root Visuals for either type of ProgressBar-->
<Border x:Name="ProgressBarTrack" CornerRadius="3" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" />
<Grid x:Name="ProgressBarRootGrid" >
<Grid Margin="1">
</Grid>
<!-- Beginning of Indeterminate Progress Bar Visuals-->
<Grid x:Name="IndeterminateRoot" Opacity="0.88" Visibility="Collapsed">
</Grid>
<!-- Beginning of Determinate Progress Bar Visuals-->
<Grid x:Name="DeterminateRoot" Margin="1" >
</Grid>
</Grid>
</Grid>
</ControlTemplate>
在行列式和不确定网格中,只需使用路径和形状绘制图像 (Storyboard.TargetProperty =“(Shape.Fill)。(LinearGradientBrush.Transform)。(TransformGroup.Children)[0] .X”LinearGradientBrush是我用来填充网格中的对象的画笔。)
<ProgressBar Template="{StaticResource CustomProgressBarTemplate}"/>
您必须使用设计,确保您只需填写正确的UIElement。我希望这对你来说是一个好的开始