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. php 获取客户端的ip、地理信息、浏览器信息、本地真实ip

    转自:http://www.blhere.com/948.html 这是非常实用的php常用类.获取客户端的ip.地理信息.浏览器信息.本地真实ip 1234567891011121314151617 ...

  2. font-weight:bolder与设置数值的区别

    我之前设置了font-weight:bolder;一直不明白为什么在浏览器上显示最后的效果就变成了normal呢,后来查了一下才发现bolder是相对父元素的. 如果父对象的值为 normal,子对象 ...

  3. HZOJ 巨神兵

    60pts: 每个DAG的拓扑序是唯一的,所以考虑将DAG分层.f[i][j]记录当前选择的节点状态是i,最后一层的节点状态为j(dep取最大). 初始状态:$f[i][i]=1;i\in [1,1& ...

  4. JavaWeb登录、注销、退出、记住用户名和密码

    应该是保存在Cookie里,session是放在服务器的内存里的.在用户关闭了网页窗口后,session就清空了.而Cookie是保存在用户的IE临时文件夹中的,再次登录时,读取其中的值传给服务器. ...

  5. python 列表长度

  6. C#面向对象基础--类与对象

    1.类与对象 类是面向对象编程的基本单元:类造出来的变量叫对象. 一个类包含俩种成员:字段与方法. 字段即变量,方法即函数. 面向对象思想:教给我们如何合理的运用类的规则去编写代码. 2.类的字段 字 ...

  7. docker compose安装gitea

    docker-compose.yml version: "3.4" networks: gitea: external: false services: server: image ...

  8. 2018-2-13-windows-10预览版升级win10-7月29-10240.16384

    title author date CreateTime categories windows 10预览版升级win10 7月29 10240.16384 lindexi 2018-2-13 17:2 ...

  9. oracle函数greatest(exp1,exp2,exp3,……,expn)

    [功能]返回表达式列表中值最大的一个.如果表达式类型不同,会隐含转换为第一个表达式类型. [参数]exp1……n,各类型表达式 [返回]exp1类型 [示例] SELECT greatest(10,3 ...

  10. 2018-8-10-win10-uwp-如何打包Nuget给其他人

    title author date CreateTime categories win10 uwp 如何打包Nuget给其他人 lindexi 2018-08-10 19:16:50 +0800 20 ...