- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
自定义控件在WPF开发中是很常见的,有时候某些控件需要契合业务或者美化统一样式,这时候就需要对控件做出一些改造.
话不多说直接看效果 。
默认效果: 上传效果
因为按钮本身没有 CornerRadius 属性,所以只能重写Button的控件模板.
<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>
在按钮的模板中加入一个Border即可,但是按钮本身没有 CornerRadius 属性,就没办法使用TemplateBinding ,只能写死在样式,那肯定不行,所以我们就需要拓展一下Button按钮.
1.创建一个类 MyProgressButton 继承Button类,由于是新创建的一个类,所以我们可以直接使用依赖属性来完成这件事,在 MyProgressButton 中定义一个圆角弧度的依赖属性.
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.创建一个 ProgressButtonStyle.xaml 的资源文件,针对 MyProgressButton 定义一些样式,包括弧度的绑定和鼠标移入移出的阴影效果,让我们的按钮立体起来 。
<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 的命名控件加入进来,并且用xaml创建一个 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>
看看效果
1.定义按钮类型 MyProgressButton 的 文件上传进度,是否上传,以及上传时按钮背景色 三个依赖属性 。
/// <summary>
/// 文件上传进度
/// </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>
/// 上传时按钮背景色
/// </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.如何实现按钮内部的进度显示?有几种办法,比如使用渐进色修改偏移,或者按钮内部套一个进度条,或者按钮内部放两个不同颜色的块控件,动态修改两者的长度。我们选择第一种.
在Progress属性被修改的时候,我们动态修改下按钮内部渐进色的偏移。为 ProgressProperty 添加值变化的回调.
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();
//设置一个横向的线
linearGradientBrush.StartPoint = new Point(0, 0.5);
linearGradientBrush.EndPoint = new Point(1, 0.5);
GradientStop gradientStop = new GradientStop(); //右边的颜色,即按钮设置的上传时背景色
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;
}
}
}
在上传文件的时候,将按钮置为禁用,防止重复点击。写一个 IsUploadingProperty 属性的值变化的回调.
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;
}
}
最后此篇关于WPF必须掌握的技能之自定义控件——实战:自制上传文件显示进度按钮的文章就讲到这里了,如果你想了解更多关于WPF必须掌握的技能之自定义控件——实战:自制上传文件显示进度按钮的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在尝试理解 promise ,在本例中是在一个循环中。 我的场景基于将文件上传到 Google 云端硬盘。我的理解是,每个文件都应该上传,然后一旦 promise 得到解决,就上传下一个文件,依此
JDK 1.6 包括通过 JAX-WS API 使用 FastInfoset Web 服务的功能。这些的实现隐藏在 com.sun.xml.internal 的深处,包名旨在让任何明智的 Java 开
我正在学习 React 并思考组件的结构。以下内容让我有些困惑。 我们被告知应该有单一的真相来源。 所有者组件应将 props/状态传递给它的责任(有些人称为“ownee”)组件。 所以,如果我自己的
我刚刚开始使用 Google Guice 作为依赖项注入(inject)框架,并试图将其改造为我最近编写的中小型项目。我了解 Guice 工作原理的基础知识,但对一些方法细节有点模糊。例如: 1) 模
上周我们在上周左右的修补和测试后将 Omniture 的分析代码发布到大量网站上。 在我们几乎所有的网站模板上,它都运行良好。在一些零星的、不可预测的情况下,严重的浏览器崩溃体验可能会让一些用户望而却
我刚刚获得了一个 API,它似乎比我习惯的更上一层楼,因为一切似乎都是使用接口(interface)实现的,我正在努力理解它们。 public partial class Form1 : Form,
我的程序似乎很合我意。但是,当我编译它时,我收到了这条消息: Note: Program.java uses unchecked or unsafe operations. Note: Recompi
最近开始用story board、Xcode等学习Swift。我很难理解 ViewController 代码的原理,因为它似乎遗漏了很多基本要素——大概是为了尝试让事情变得更简单——但它不适合来自其他
我刚收到一些有关使用 wpf、c# 的 MVVM 的设计/实现问题。我只是想掌握 MVVM,如果有人能证实我的想法,我正在徘徊,在我的应用程序中,我需要一名员工、一个部门和一家公司。所以换句话说,我有
我在 gird View 中有一个 gridview 和 2 个链接按钮,编辑和删除,单击编辑按钮 s 时,该行的详细信息应显示在“detailsview”中。我的详细信息 View 在更新面板。 最
function def() { console.log(this.x) } var f = def.bind({ x:777 }) f() // prints 777 bind 创建了一个函
我尝试将谷歌地图(外部加载的脚本)添加到 meteor 应用程序,但没有成功,我注意到有两种问题: 如果我做简单的事情并将主要的 API 脚本添加到我的 ,然后它被呈现为last。 发生这种情况时,
如果我理解正确,Node JS 是非阻塞的......所以它不是等待来自数据库或其他进程的响应,而是转移到其他东西并稍后再检查。 它也是单线程的。 这是否意味着给定的 Node JS 进程可以充分有效
几周前,我开始了 Iphone 应用程序开发的研究,在不同设置中进行了大量的 hello world 应用程序之后,我现在已经准备好开发我的第一个基于 Cocoa 中使用的 MVC 设计模式的应用程序
这个问题和我之前的问题很相似。 大约 4 年前,我在 Visual Studio 2005 中使用过 ASP .Net。恢复最新版本需要多长时间? 最佳答案 这取决于您“使用”它的程度。有经验的开发人
如何让这个程序让用户一次输入 5 位数字,而不是每次都询问单独的数字?我知道我必须使用 string.split() 但我将在哪里放置代码并执行代码。 Heading from random impo
因此,根据我的理解,在 3nf 数据库中,主键值可用于确定表中的每个其他属性。 这是否意味着外键将专门用于创建复合实体?外键如何适合 3nf 数据库? 有哪些“迹象”表明我的数据库已标准化?数据库中的
如何解决以下 f(n)=n!据我所知不适用于主定理的任何情况。T(n) = 16T(n/4) + n! 最佳答案 David Eisenstat 部分正确。情况 3 确实适用,但 T(n) = the
在过去的 2.5 年里,我一直在研究 SAP 技术。由于技术概念太多,我无法找到一个可以了解与它相关的所有内容的单一来源。我没有掌握掌握所有技术概念的信心。 如果您遇到过这样的经历以及如何克服它,请帮
我是一名优秀的程序员,十分优秀!