title author date CreateTime categories
win10 uwp 按下等待按钮
lindexi
2018-08-10 19:16:50 +0800
2018-2-13 17:23:3 +0800
Win10 UWP

我们经常需要一个按钮,在按下时,后台执行Task,这时不能再次按下按钮。

我们使用自定义控件,首先新建一个类,我把它命名是ProgressButton

一个进度条按钮,也就是我们按下时发生进度条,完成时他又是按钮。

我们需要一个值让我们知道是不是已经完成了后台,按钮可以按下,在按下时,自动让按钮IsEnable为false。

我们需要模板有TextBlock,显示文字,ProgressRing显示进度条。

于是我们使用TemplatePart

    [TemplatePart(Name = "TextBlock", Type = typeof(TextBlock))]
[TemplatePart(Name = "Progress", Type = typeof(Windows.UI.Xaml.Controls.ProgressRing))]
public class ProgressButton : Windows.UI.Xaml.Controls.Button

依赖属性其实很简单,我们需要在VS上大propdp 按Tab 就可以看到vs帮我们写的依赖属性。

我们需要修改属性名称,属性类型,默认值。

我这里的Text ,需要他修改时使用函数,这个叫CallBack。

依赖函数使用DependencyProperty.Register

他参数: name 是 属性名, propertyType 是属性类型, ownerType 是属于的类的类型, typeMetadata 是默认值和修改时使用函数

我们来说下 typeMetadata

typeMetadata 可以传入一个默认值,这个值就是我们不在依赖属性赋值,就给他一个默认的值。然后我们还可以给他一个在属性修改时使用的函数。

注意我们给他的函数不是必需,一般都不需要。

如果需要给他一个函数,这个函数需要有参数DependencyObject sender, DependencyPropertyChangedEventArgs e

其中 sender 是发送的实例,我们知道属性属于哪个类,我在这里,是属于ProgressButton ,我就可以使用 ProgressButton button = sender as ProgressButton;得到类,注意我们写的函数是静态的,所以sender才有用,我们可以使用sender获得类的属性

e 是有 NewValue 和 OldValue , NewValue 是我们要修改的值, OldValue 是原来的值。

大概需要的依赖属性在我们这个控件有 Text Complete 就没了。

Text是我们按钮的文字,Complete 是我们的后台是不是在执行,如果是的话,按钮就无法点击,显示进度条。

代码:

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; namespace lindexi.uwp.control.Button.Control
{
[TemplatePart(Name = "TextBlock", Type = typeof(TextBlock))]
[TemplatePart(Name = "Progress", Type = typeof(Windows.UI.Xaml.Controls.ProgressRing))]
public class ProgressButton : Windows.UI.Xaml.Controls.Button
{
public ProgressButton()
{
DefaultStyleKey = typeof(ProgressButton);
Click += ProgressButton_Click;
} private void ProgressButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
Complete = false;
} private Windows.UI.Xaml.Controls.TextBlock _textBlock; private Windows.UI.Xaml.Controls.ProgressRing _proress; public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
} // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(ProgressButton), new PropertyMetadata("",
(d, e) =>
{
ProgressButton temp = d as ProgressButton;
if (temp == null)
{
return;
}
if(temp._textBlock!=null)
{
temp._textBlock.Text = (string) e.NewValue;
}
})); public bool Complete
{
get { return (bool)GetValue(CompleteProperty); }
set { SetValue(CompleteProperty, value); }
} // Using a DependencyProperty as the backing store for Complete. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CompleteProperty =
DependencyProperty.Register("Complete", typeof(bool), typeof(ProgressButton), new PropertyMetadata(true,
OnComplete)); private static void OnComplete(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ProgressButton button = d as ProgressButton;
if (button == null)
{
return;
} bool temp = (bool)e.NewValue; //button._textBlock.Visibility = temp ? Visibility.Visible : Visibility.Collapsed;
button._proress.Visibility = temp ? Visibility.Collapsed : Visibility.Visible;
button.IsEnabled = temp;
} protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
_textBlock = GetTemplateChild("TextBlock") as Windows.UI.Xaml.Controls.TextBlock;
_proress = GetTemplateChild("Progress") as Windows.UI.Xaml.Controls.ProgressRing; if (_textBlock != null)
{
_textBlock.Visibility = Visibility.Visible;
_textBlock.Text = Text;
} if (_proress != null)
{
_proress.Visibility=Visibility.Collapsed;
}
}
}
}

我们在控件 OnApplyTemplate 拿到 _textBlock _proress 我们需要写一个Style

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:control="using:lindexi.uwp.control.Button.Control">
<Style TargetType="control:ProgressButton">
<Setter Property="Background" Value="{ThemeResource ButtonBackground}"/>
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}"/>
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}"/>
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/>
<Setter Property="Padding" Value="8,4,8,4"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="FocusVisualMargin" Value="-3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="control:ProgressButton">
<Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}"></DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPressed}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPressed}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}"/>
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundDisabled}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushDisabled}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundDisabled}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundDisabled}"></DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
AutomationProperties.AccessibilityView="Raw"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"
Content="{TemplateBinding Content}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<TextBlock x:Name="TextBlock" Margin="10,10,10,10"
HorizontalAlignment="Center"
VerticalAlignment="Center"></TextBlock>
<ProgressRing x:Name="Progress" IsActive="True"></ProgressRing> </Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

这个是从Button复制,就改了Button为 control:ProgressButton

我们要使用按钮,需要在资源写

    <Page.Resources>
<ResourceDictionary Source="Control/ProgressButton.xaml"></ResourceDictionary>
</Page.Resources>

然后就可以使用 ProgressButton ,我写ProgressButton在control文件夹,我需要在命名空间xmlns:control="using:lindexi.uwp.control.Button.Control"

 <control:ProgressButton Text="确定"
Complete="{x:Bind View.Complete,Mode=TwoWay}"
Click="ButtonBase_OnClick"></control:ProgressButton>

我上面是测试,点击是进行100秒,过了就完成,代码简单,如果想知道,戳此链接 https://github.com/lindexi/UWP/tree/master/uwp/control/Button

那么如果我们有好多个页面都用到 ProgressButton ,我们需要在所有页面都写 ResourceDictionary 这样不好,我们有一个简单方法,让页面不用写这个。

在解决方案新建一个文件夹Themes,注意命名一定是Themes,注意有个名称后面有个s,我就在这坑好多天了。

然后新建资源字典 Generic.xaml ,注意名称也是不能自己修改。

在 Generic.xaml 合并字典

    <ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///Control/ProgressButton.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>

这样我们就可以在页面直接用。

如果使用遇到问题,欢迎讨论。

参见:http://www.cnblogs.com/ms-uap/p/5520872.html

2018-8-10-win10-uwp-按下等待按钮的更多相关文章

  1. win10 uwp 按下等待按钮

    我们经常需要一个按钮,在按下时,后台执行Task,这时不能再次按下按钮. 我们使用自定义控件,首先新建一个类,我把它命名是ProgressButton 一个进度条按钮,也就是我们按下时发生进度条,完成 ...

  2. win10 uwp 毛玻璃

    毛玻璃在UWP很简单,不会和WPF那样伤性能. 本文告诉大家,如何在 UWP 使用 win2d 做毛玻璃. 毛玻璃可以使用 win2D 方法,也可以使用 Compositor . 使用 win2d 得 ...

  3. win10专业版Hyper-v下Docker挂载volume的方式使用Gitlab(汉化版)保存资料数据(使用外部redis)

    目录 话题 (191) 笔记 (137) 资料区 (2) 评价 (33) 介绍 讨论区 话题 win10专业版Hyper-v下Docker挂载volume的方式使用Gitlab(汉化版)保存资料数据( ...

  4. win10 uwp 使用 Microsoft.Graph 发送邮件

    在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ...

  5. Win10/UWP开发—使用Cortana语音与App后台Service交互

    上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...

  6. win10 uwp 列表模板选择器

    本文主要讲ListView等列表可以根据内容不同,使用不同模板的列表模板选择器,DataTemplateSelector. 如果在 UWP 需要定义某些列的显示和其他列不同,或者某些行的显示和其他行不 ...

  7. 【广告】win10 uwp 水印图床 含代码

    本文主要是广告我的软件. 图床可以加速大家写博客上传图片的时间,通过简化我们的操作来得到加速. 在写博客的时候,我们发现,我们需要上传一张图片,需要先打开图片,然后选择本地图片,然后上传. 但是我经常 ...

  8. win10 uwp 入门

    UWP是什么我在这里就不说,本文主要是介绍如何入门UWP,也是合并我写的博客. 关于UWP介绍可以参见:http://lib.csdn.net/article/csharp/32451 首先需要申请一 ...

  9. win10 uwp 商业游戏

    本文告诉大家去做一个商业游戏,游戏很简单,几乎没有什么技术 游戏的开始,需要添加框架库,于是引用我自己写的库. 首先是创建一个启动页面,这个页面是显示启动的. 在显示启动的时候,是需要加载游戏需要使用 ...

随机推荐

  1. bzoj1221 软件开发

    Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员 ...

  2. mysql操作手册2

          6 rows in set (0.00 sec) # 我们再把 table 的位置交换一下,再用 right join 试试 select a.id,a.name,b.dept_id fr ...

  3. firefox扩展开发(二):用XUL创建窗口控件

    firefox扩展开发(二):用XUL创建窗口控件 2008-06-11 16:57 1.创建一个简单的窗口 <?xml version="1.0"?> <?xm ...

  4. 【Leetcode链表】移除链表元素(203)

    题目 删除链表中等于给定值 val 的所有节点. 示例: 输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3-&g ...

  5. laravel 操作日志;

    在网上寻找了许多方法,觉得有的地方看不懂,  决定自己写一些关于laravel中调用本身中的操作日志: Laravel 日志工具在强大的 Monolog 函数库上提供一层简单的功能.Laravel 默 ...

  6. KiCad 5.1.0 镜像圆弧后错位问题

    KiCad 5.1.0 镜像圆弧后错位问题 看官方回复这个问题将在 5.1.3 进行修复,因为这段时间在举行 KiCon 活动. 看到这个问题并不是非常严重,不是致命的,所以已经从 5.1.0 跳到 ...

  7. Cython保护Python代码

    注:.pyc也有一定的保护性,容易被反编译出源码... 项目发布时,为防止源码泄露,需要对源码进行一定的保护机制,本文使用Cython将.py文件转为.so进行保护.这一方法,虽仍能被反编译,但难度会 ...

  8. Codeforces 662D International Olympiad【贪心】

    比赛的时候后缀长度在4位以内的时候分类讨论了一下,其实他们完全是一个套路的..并不需要讨论. 然后没有考虑前导0的情况,就wa了.. 题目链接: http://codeforces.com/probl ...

  9. python基础---集合类型(Sets)

    集合类型(Sets) 集合对象是不同的(不可重复)hashable对象的无序集合.常见用法包括:成员关系测试.移除序列中的重复.以及科学计算,例如交集.并集.差分和对称差分.通俗点来说,集合是一个无序 ...

  10. top 9 Cloud Computing Failures

    top 9 Cloud Computing Failures Outages, hacks, bad weather, human error and other factors have led t ...