我會給你一個關於如何從該模板製作工作進度條的想法。
首先,我們創建自定義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
現在我無法找到他們之前找到解決辦法......雖然你已經構建的東西,看起來像一個進度條,它是靜態的,使填充路徑變化,根據進展值會非常困難。您最好使用進度條的默認控制模板並將其調整爲您想要的樣子。 –