zoukankan      html  css  js  c++  java
  • 2018-8-10-win10-uwp-按下等待按钮

    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

  • 相关阅读:
    做题遇到的问题集合
    常见算法和数据结构存在的坑(updating)
    Loj#2090. 「ZJOI2016」旅行者(网格图分治)
    洛谷P3332 [ZJOI2013]K大数查询(整体二分板题)
    dij费用流模板
    KM求每个大小的匹配的最优解 模板
    JZOJ 5067. 【GDOI2017第二轮模拟day2】有理有据题 (KD-tree+历史最值问题)
    Codeforces 1186F. Vus the Cossack and a Graph(欧拉回路)
    bzoj#2095. [Poi2010]Bridges(二分+混合图欧拉回路)
    二维最小乘积生成树模板
  • 原文地址:https://www.cnblogs.com/lindexi/p/12086486.html
Copyright © 2011-2022 走看看