我会给你一个关于如何从该模板制作工作进度条的想法。
首先,我们创建自定义WPF控件和继承进度:
public class MyProgressBar : ProgressBar {
static MyProgressBar() {
DefaultStyleKeyProperty.OverrideMetadata(typeof (MyProgressBar), new FrameworkPropertyMetadata(typeof (MyProgressBar)));
}
}
然后我们走在主题/ Generic.xaml文件(该文件是为我们通过Visual Studio中,如果不存在创建),并创建外观我们的控制:
<local:MyProgressBarWidthConverter x:Key="width" />
<Style TargetType="{x:Type local:MyProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyProgressBar}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Viewbox Stretch="Fill">
<Canvas x:Name="Progress1" ClipToBounds="True" HorizontalAlignment="Left" Height="52" UseLayoutRounding="False" VerticalAlignment="Top" Width="493">
<Canvas x:Name="Loading" Height="52" Canvas.Left="0" Canvas.Top="0" Width="493">
<Path x:Name="Base2" Data="F1M22.086,3C22.086,3 63.118,4.562 125.833,3 199.069,1.175 294.072,5.645 370.146,4.333 430.323,3.294 474,3 474,3 479.523,3 487.826,8.208 489.687,15.098 491.864,23.156 491.191,28.867 489.081,37.118 487.415,43.637 479.856,47.999 474.333,47.999 474.333,47.999 368.324,50.176 252.792,47.999 135.568,45.792 42.104,49.541 23.518,47.999 12.306,47.07 6.028,45.811 4.028,37.787 3.199,34.461 1.441,23.222 7.178,11.906 10.179,5.987 16.563,3 22.086,3z" Height="52" Canvas.Left="0" Canvas.Top="0" Width="493" StrokeThickness="2">
<Path.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC18A13" Offset="1"/>
<GradientStop Color="#FFDC9A0C" Offset="0.339"/>
</LinearGradientBrush>
</Path.Stroke>
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFE4882D" Offset="0"/>
<GradientStop Color="#FFF5CA09" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
</Path>
<Path x:Name="Bg" Data="F1M16.361,2.603C16.361,2.603 133.014,3.416 247.396,3.478 311.817,3.513 376.242,2.615 416.922,1.936 446.114,1.448 458.772,2.411 458.772,2.411 462.592,2.411 469.449,4.823 471.077,9.484 473.896,17.557 472.201,20.776 471.202,25.468 470.232,30.02 467.977,31.719 459.43,33.25 450.883,34.782 424.628,32.594 376,32.594 298.703,32.594 184.467,31.065 105.75,30.911 54.767,30.812 18.683,32.063 17.185,32.063 9.403,32.063 6.954,28.298 5.436,25.402 4.335,23.303 1.86,15.809 6.797,8.253 9.308,4.41 12.541,2.603 16.361,2.603z" Fill="#FFA77235" Height="36" Canvas.Left="9" Canvas.Top="8" Width="475"/>
<Viewbox Stretch="UniformToFill" Canvas.Left="8" Canvas.Top="7" Height="36">
<Viewbox.Width>
<MultiBinding Converter="{StaticResource width}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum" />
</MultiBinding>
</Viewbox.Width>
<Path x:Name="Progress" Data="F1M19.986,2.29C19.986,2.29 50.058,4.582 104.021,2.936 154.279,1.403 214.797,4.02 264,4.02 310.844,4.02 341.117,2.457 347.659,2.936 354.201,3.415 356.173,5.804 357.743,10.484 359.313,15.162 360.055,20.568 357.202,26.468 355.175,30.658 353.597,31.417 347.492,33.396 345.484,34.047 309.622,34.937 262.208,34.943 217.536,34.948 162.63,33.886 116.105,33.683 61.905,33.446 19.087,34.063 17.185,34.063 9.403,34.063 6.016,31.048 4.498,28.152 3.397,26.053 1.86,15.809 6.797,8.253 9.308,4.41 16.166,2.29 19.986,2.29z" >
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="#FF5DFF4E" Offset="0.409"/>
<GradientStop Color="#FF159308" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
</Path>
</Viewbox>
</Canvas>
</Canvas>
</Viewbox>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
基本上我们只是把整个画布从你的PSD内Viewbox控件与弹力=填充(也去除不需要的利润)。请注意,所有大小都是相同的,并且是硬编码的,但是因为我们将控件放在视图框内,它将伸展到视图框的大小。并且因为这是带有Stretch = Fill而没有指定宽度和高度的viewbox,它会延伸到控件的大小。我们还将对应于绿色填充的路径放到它自己的viewbox中,因为我们需要根据ProgressBar.Value参数调整该路径的大小。
现在我们创建绿色路径的视框中宽度转换器:
public class MyProgressBarWidthConverter : IMultiValueConverter {
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
if (values.Any(c => c == null || c == DependencyProperty.UnsetValue))
return 0.0d;
var min = (double) values[0];
var current = (double) values[1];
var max = (double) values[2];
const double maxWidth = 475; // that is from template
return (current/(max - min))*maxWidth;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
throw new NotImplementedException();
}
}
有我们传递最小,价值,进度条的最大和计算绿条的宽度。最大可用宽度总是475,但记住我们把它放在viewbox中,所以我们的控件是而不是固定为475宽度。
然后我们把控制窗口:
<wpf:MyProgressBar x:Name="bar" Width="500" Height="50" Value="5" Minimum="0" Maximum="100" />
代码隐藏:
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
var timer = new DispatcherTimer()
{
Interval = TimeSpan.FromSeconds(1)
};
timer.Tick += (o, e) =>
{
if (bar.Value < bar.Maximum)
bar.Value++;
else
timer.Stop();
};
timer.Start();
}
}
,看我们如何工作进度。 一般而言,如果您的UI很繁重,则可能需要使用简单的表单,因为视框内的许多路径效率不高。但如果你有来自PSD的固定路径......为什么不。
编辑回答您的评论。当然,不需要创建新的控制,它更加灵活。如果你不希望这样做,只是创建控件模板为你的进度条,并分配到现有ProgressBar.ControlTemplate,像这样:
<Window x:Class="Wpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpf="clr-namespace:Wpf"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<wpf:MyProgressBarWidthConverter x:Key="width" />
<ControlTemplate x:Key="myProgressBar" TargetType="{x:Type ProgressBar}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Viewbox Stretch="Fill">
<Canvas x:Name="Progress1" ClipToBounds="True" HorizontalAlignment="Left" Height="52" UseLayoutRounding="False" VerticalAlignment="Top" Width="493">
<Canvas x:Name="Loading" Height="52" Canvas.Left="0" Canvas.Top="0" Width="493">
<Path x:Name="Base2" Data="F1M22.086,3C22.086,3 63.118,4.562 125.833,3 199.069,1.175 294.072,5.645 370.146,4.333 430.323,3.294 474,3 474,3 479.523,3 487.826,8.208 489.687,15.098 491.864,23.156 491.191,28.867 489.081,37.118 487.415,43.637 479.856,47.999 474.333,47.999 474.333,47.999 368.324,50.176 252.792,47.999 135.568,45.792 42.104,49.541 23.518,47.999 12.306,47.07 6.028,45.811 4.028,37.787 3.199,34.461 1.441,23.222 7.178,11.906 10.179,5.987 16.563,3 22.086,3z" Height="52" Canvas.Left="0" Canvas.Top="0" Width="493" StrokeThickness="2">
<Path.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC18A13" Offset="1"/>
<GradientStop Color="#FFDC9A0C" Offset="0.339"/>
</LinearGradientBrush>
</Path.Stroke>
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFE4882D" Offset="0"/>
<GradientStop Color="#FFF5CA09" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
</Path>
<Path x:Name="Bg" Data="F1M16.361,2.603C16.361,2.603 133.014,3.416 247.396,3.478 311.817,3.513 376.242,2.615 416.922,1.936 446.114,1.448 458.772,2.411 458.772,2.411 462.592,2.411 469.449,4.823 471.077,9.484 473.896,17.557 472.201,20.776 471.202,25.468 470.232,30.02 467.977,31.719 459.43,33.25 450.883,34.782 424.628,32.594 376,32.594 298.703,32.594 184.467,31.065 105.75,30.911 54.767,30.812 18.683,32.063 17.185,32.063 9.403,32.063 6.954,28.298 5.436,25.402 4.335,23.303 1.86,15.809 6.797,8.253 9.308,4.41 12.541,2.603 16.361,2.603z" Fill="#FFA77235" Height="36" Canvas.Left="9" Canvas.Top="8" Width="475"/>
<Viewbox Stretch="UniformToFill" Canvas.Left="8" Canvas.Top="7" Height="36">
<Viewbox.Width>
<MultiBinding Converter="{StaticResource width}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value" />
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum" />
</MultiBinding>
</Viewbox.Width>
<Path x:Name="Progress" Data="F1M19.986,2.29C19.986,2.29 50.058,4.582 104.021,2.936 154.279,1.403 214.797,4.02 264,4.02 310.844,4.02 341.117,2.457 347.659,2.936 354.201,3.415 356.173,5.804 357.743,10.484 359.313,15.162 360.055,20.568 357.202,26.468 355.175,30.658 353.597,31.417 347.492,33.396 345.484,34.047 309.622,34.937 262.208,34.943 217.536,34.948 162.63,33.886 116.105,33.683 61.905,33.446 19.087,34.063 17.185,34.063 9.403,34.063 6.016,31.048 4.498,28.152 3.397,26.053 1.86,15.809 6.797,8.253 9.308,4.41 16.166,2.29 19.986,2.29z" >
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="#FF5DFF4E" Offset="0.409"/>
<GradientStop Color="#FF159308" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
</Path>
</Viewbox>
</Canvas>
</Canvas>
</Viewbox>
</Border>
</ControlTemplate>
</Window.Resources>
<ProgressBar x:Name="bar" Width="500" Height="50" Value="5" Minimum="0" Maximum="100" Template="{StaticResource myProgressBar}"/>
我见过的约3个问题在上个月完全一样的.. –
@GlenThomas你能不能请张贴链接到他们?我总是问thying新问题 – Misiu
现在我无法找到他们之前找到解决办法......虽然你已经构建的东西,看起来像一个进度条,它是静态的,使填充路径变化,根据进展值会非常困难。您最好使用进度条的默认控制模板并将其调整为您想要的样子。 –