WPF自定義實(shí)現(xiàn)上傳文件顯示進(jìn)度的按鈕控件
話不多說直接看效果
默認(rèn)效果:
上傳效果:
按鈕設(shè)置圓角
因?yàn)榘粹o本身沒有CornerRadius屬性,所以只能重寫B(tài)utton的控件模板。
<Style TargetType="Button"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border CornerRadius="5" Width="{TemplateBinding Width}" Background="{TemplateBinding Background}" BorderThickness="1" Height="{TemplateBinding Height}"> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
在按鈕的模板中加入一個(gè)Border即可,但是按鈕本身沒有CornerRadius屬性,就沒辦法使用TemplateBinding ,只能寫死在樣式,那肯定不行,所以我們就需要拓展一下Button按鈕。
1.創(chuàng)建一個(gè)類MyProgressButton繼承Button類,由于是新創(chuàng)建的一個(gè)類,所以我們可以直接使用依賴屬性來完成這件事,在MyProgressButton中定義一個(gè)圓角弧度的依賴屬性。
public CornerRadius CornerRadius { get { return (CornerRadius)GetValue(CornerRadiusProperty); } set { SetValue(CornerRadiusProperty, value); } } public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register(nameof(CornerRadius), typeof(CornerRadius), typeof(MyProgressButton), new PropertyMetadata(default));
2.創(chuàng)建一個(gè)ProgressButtonStyle.xaml的資源文件,針對MyProgressButton定義一些樣式,包括弧度的綁定和鼠標(biāo)移入移出的陰影效果,讓我們的按鈕立體起來
<Style TargetType="local:MyProgressButton"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:MyProgressButton"> <Border CornerRadius="{TemplateBinding CornerRadius}" Width="{TemplateBinding Width}" Background="{TemplateBinding Background}" BorderThickness="1" Height="{TemplateBinding Height}"> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Border> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="IsMouseOver" Value="False"> <Setter Property="Effect"> <Setter.Value> <DropShadowEffect Color="#cccccc" Direction="270" ShadowDepth="2" Opacity="1" /> </Setter.Value> </Setter> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Effect" > <Setter.Value> <DropShadowEffect Color="#bbbbbb" Direction="270" ShadowDepth="2" Opacity="1" /> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style>
3.最后在主界面將MyProgressButton的命名控件加入進(jìn)來,并且用xaml創(chuàng)建一個(gè)MyProgressButton按鈕,自定義一些屬性,并且將ProgressButtonStyle.xaml樣式加入到App.xaml中
<Window x:Class="ProgressButton.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:local="clr-namespace:ProgressButton" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <local:MyProgressButton Content="上傳文件" Foreground="#555555" Cursor="Hand" FontSize="14" CornerRadius="5" HorizontalAlignment="Center" VerticalAlignment="Center" Height="40" Width="135" Background="Salmon" x:Name="upload_btn"> </local:MyProgressButton> </Grid> </Window>
<Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="pack://application:,,,/ProgressButton;component/Button/ProgressButtonStyle.xaml"></ResourceDictionary> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources>
看看效果:
按鈕上傳文件相關(guān)定義
1.定義按鈕類型MyProgressButton的文件上傳進(jìn)度,是否上傳,以及上傳時(shí)按鈕背景色三個(gè)依賴屬性
/// <summary> /// 文件上傳進(jìn)度 /// </summary> public double Progress { get { return (double)GetValue(ProgressProperty); } set { SetValue(ProgressProperty, value); } } public static readonly DependencyProperty ProgressProperty = DependencyProperty.Register(nameof(Progress), typeof(double), typeof(MyProgressButton), new PropertyMetadata(double.NegativeZero, OnProgressChanged)); /// <summary> /// 文件是否上傳 /// </summary> public bool IsUploading { get { return (bool)GetValue(IsUploadingProperty); } set { SetValue(IsUploadingProperty, value); } } public static readonly DependencyProperty IsUploadingProperty = DependencyProperty.Register(nameof(IsUploading), typeof(bool), typeof(MyProgressButton), new PropertyMetadata(false, OnIsUploadingChanged)); /// <summary> /// 上傳時(shí)按鈕背景色 /// </summary> public Color UploadingColor { get { return (Color)GetValue(UploadingColorProperty); } set { SetValue(UploadingColorProperty, value); } } // Using a DependencyProperty as the backing store for UploadingColor. This enables animation, styling, binding, etc... public static readonly DependencyProperty UploadingColorProperty = DependencyProperty.Register(nameof(UploadingColor), typeof(Color), typeof(MyProgressButton), new PropertyMetadata(Colors.White));
2.如何實(shí)現(xiàn)按鈕內(nèi)部的進(jìn)度顯示?有幾種辦法,比如使用漸進(jìn)色修改偏移,或者按鈕內(nèi)部套一個(gè)進(jìn)度條,或者按鈕內(nèi)部放兩個(gè)不同顏色的塊控件,動(dòng)態(tài)修改兩者的長度。我們選擇第一種。
在Progress屬性被修改的時(shí)候,我們動(dòng)態(tài)修改下按鈕內(nèi)部漸進(jìn)色的偏移。為ProgressProperty添加值變化的回調(diào)。
private static void OnProgressChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var btn = d as MyProgressButton; var progress = (double)e.NewValue; if (progress != double.NegativeZero) { Brush brush = null; if ((brush = btn.Background as LinearGradientBrush) != null) //如果按鈕本身是線性漸變色則直接修改偏移 { GradientStopCollection collections = brush.GetValue(GradientBrush.GradientStopsProperty) as GradientStopCollection; collections[1].Offset = collections[0].Offset = progress / 100; } else //如果本身不是線性漸變色則將背景色修改為線性漸變色 { LinearGradientBrush linearGradientBrush = new LinearGradientBrush(); //設(shè)置一個(gè)橫向的線 linearGradientBrush.StartPoint = new Point(0, 0.5); linearGradientBrush.EndPoint = new Point(1, 0.5); GradientStop gradientStop = new GradientStop(); //右邊的顏色,即按鈕設(shè)置的上傳時(shí)背景色 gradientStop.Color = btn!.UploadingColor; GradientStop gradientStop1 = new GradientStop();//左邊的顏色,即按鈕原本的顏色 gradientStop1.Color = (btn!.Background as SolidColorBrush)!.Color; gradientStop.Offset = gradientStop1.Offset = progress / 100; linearGradientBrush.GradientStops.Add(gradientStop1); linearGradientBrush.GradientStops.Add(gradientStop); btn.Background = linearGradientBrush; } } }
在上傳文件的時(shí)候,將按鈕置為禁用,防止重復(fù)點(diǎn)擊。寫一個(gè)IsUploadingProperty屬性的值變化的回調(diào)。
private static void OnIsUploadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var btn = d as MyProgressButton; if ((bool)e.NewValue) { btn!.IsEnabled = false; } else { btn!.IsEnabled = true; } }
測試代碼
Binding binding = new Binding(); binding.Source = this; binding.Path = new PropertyPath("Progress"); binding.Mode = BindingMode.OneWay; upload_btn.SetBinding(MyProgressButton.ProgressProperty, binding); Binding binding1 = new Binding(); binding1.Source = this; binding1.Path = new PropertyPath("IsUploading"); binding1.Mode = BindingMode.OneWay; upload_btn.SetBinding(MyProgressButton.IsUploadingProperty, binding1);
private async void upload_btn_Click(object sender, RoutedEventArgs e) { IsUploading = true; try { using (FileStream fread = new FileStream("d://d3dcompiler_47.dll", FileMode.Open, FileAccess.Read)) using (FileStream fwrite = new FileStream("d://d3dcompiler_47_copy.dll", FileMode.OpenOrCreate, FileAccess.Write)) { var allLength = new FileInfo("d://d3dcompiler_47.dll").Length; long copyedBytes = 0; while (true) { var buffer = ArrayPool<byte>.Shared.Rent(1024 * 10); try { var len = await fread.ReadAsync(buffer, 0, buffer.Length); if (len > 0) { await fwrite.WriteAsync(buffer[..len]); copyedBytes += len; Progress = copyedBytes * 100 / allLength; await Task.Delay(20); } else { break; } } catch { break; } finally { ArrayPool<byte>.Shared.Return(buffer); } } MessageBox.Show("上傳成功"); }; } finally { IsUploading = false; } }
到此這篇關(guān)于WPF自定義實(shí)現(xiàn)上傳文件顯示進(jìn)度的按鈕控件的文章就介紹到這了,更多相關(guān)WPF自定義控件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#利用Spire.Pdf包實(shí)現(xiàn)為PDF添加數(shù)字簽名
Spire.PDF for .NET 是一款專業(yè)的基于.NET平臺的PDF文檔控制組件。它能夠讓開發(fā)人員在不使用Adobe Acrobat和其他外部控件的情況下,運(yùn)用.NET 應(yīng)用程序創(chuàng)建,閱讀,編寫和操縱PDF 文檔。本文將利用其實(shí)現(xiàn)添加數(shù)字簽名,需要的可以參考一下2022-08-08c# GridControl的模糊查詢實(shí)現(xiàn)代碼
這篇文章主要介紹了c# GridControl的模糊查詢實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-02-02DevExpress之ChartControl的SeriesTemplate實(shí)例
這篇文章主要介紹了DevExpress之ChartControl的SeriesTemplate用法實(shí)例,實(shí)現(xiàn)了餅狀Series百分比顯示的效果,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-10-10C#微信公眾號開發(fā)之用戶上下文WeixinContext和MessageContext
這篇文章介紹了C#微信公眾號開發(fā)之用戶上下文WeixinContext和MessageContext,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06Unity3D實(shí)現(xiàn)模型隨機(jī)切割
這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)模型隨機(jī)切割,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03