`
lindexi-gd
  • 浏览: 139549 次
社区版块
存档分类
最新评论

win10 uwp 验证输入 自定义用户控件

 
阅读更多

TextBox是给用户输入,我们有时要用户只输入数字,而用户输入汉字,我们就有提示用户,那么这东西用到次数很多,我们需要做成一个控件。

我们可以用别人的库,我找到一个大神写的库,很好用

我们使用这个库可以定义很多验证,我记录我如何使用他这个库,还有如何去修改这个库。如何自定义控件做一个和大神做的一样的控件。

<!--more-->
<!-- csdn -->

Nuget

我们用这个库是jamescroft写的,他上传到Nuget,我们可以去下载

用Nuget搜索WinUX.UWP.Xaml.Controls

下载完成就好

使用库

我们经常需要验证用户输入,不是使用一个规则,是有很多规则。我们常用的规则也就几个,数字、URL……

我们下载库,有常用规则

– DateTimeValidationRule
日期规则,输入可以转日期

– DecimalValidationRule
数字,输入可以转数字

– DoubleValidationRule
输入可以转浮点

– EmailValidationRule
邮箱,输入是mail

– IntValidationRule
整形,输入可以转整形

– RegexValidationRule
我们自己定义正则,有时我们需要复杂的,要求长度

– UrlValidationRule
输入是URL

我们要在资源定义,因为我们有多条验证

先写,因为我们引用库和我的不知一空间

     xmlns:validation="using:WinUX.Data.Validation"
     xmlns:rules="using:WinUX.Data.Validation.Rules"
     xmlns:controls="using:WinUX.Xaml.Controls"

在资源定义,我们需要多条,看起来好长,如果我们要用两次,那么还是写资源

        <Grid.Resources>
            <validation:ValidationRules x:Key="UrlSample">
                <validation:ValidationRules.Rules>
                    <rules:UrlValidationRule />
                </validation:ValidationRules.Rules>
            </validation:ValidationRules>
        </Grid.Resources>

下面直接抄大神写的

     <controls:ValidatingTextBox IsMandatory="True" Header="Website" Text="http://www.jamescroft.co.uk" 
                                    MaxLength="50" 
                                    ValidationRules="{StaticResource Url}" 
                                    VerticalAlignment="Center"/>

MaxLength 最大长度

ValidationRules 验证规则

<!-- `IsMandatory` &#36755;&#20837;&#26159;&#21542;&#23545;&#10;&#10;&#36825;&#20010;&#20540;&#32465;&#23450;&#21040;ViewModel&#21487;&#20197;&#24471;&#21040;&#26159;&#21542;&#21487;&#20197;&#36755;&#20837;&#21040;ViewModel -->

IsMandatory 输入规则

MandatoryValidationMessage 输入规则提示

如果IsMandatory=true在没有输入,显示MandatoryValidationMessage

IsInvalid 输入是否对

这个值绑定到ViewModel可以得到是否可以输入到ViewModel

如果我们需要写输入错了提示

     <rules:UrlValidationRule ErrorMessage="输入错"></rules:UrlValidationRule>

如果需要使用正则,我们的验证复制,需要使用RegexValidationRule,在Regex写正则

        <controls:ValidatingTextBox IsMandatory="True" Header="Website" Text="" 
                                    MaxLength="0" MandatoryValidationMessage="输入" 
                                    VerticalAlignment="Center">
            <controls:ValidatingTextBox.ValidationRules>
               <validation:ValidationRules>
                   <validation:ValidationRules.Rules>
                        <rules:RegexValidationRule Regex="mailto:\w+([-+.]\w+)*@\w+([-.]\w+)*.\w+([-.]\w+)*"></rules:RegexValidationRule>
                   </validation:ValidationRules.Rules>
               </validation:ValidationRules>
            </controls:ValidatingTextBox.ValidationRules>
            <controls:ValidatingTextBox.ValidationTextBlock >
                <TextBlock Text="ValidationTextBlock"></TextBlock>
            </controls:ValidatingTextBox.ValidationTextBlock>
        </controls:ValidatingTextBox>

使用很简单,那么这如何做。

下面我来说下,他这个如何做,这有些复杂,我们分开来说,开始是功能

判断输入字符长度

我们需要一个TextBlock来显示最大长度、现在字符长度

我们的TextBlock的名称remainingCharacters,在输入变化修改

        private void UpdateRemainingCharacters()
        {
            //判断不为空
            if (this.remainingCharacters != null)
            {
                //如果最大长度==0,不显示
                if (this.MaxLength == 0)
                {
                    this.remainingCharacters.Visibility = Visibility.Collapsed;
                    return;
                }

                //Text是现在字符,我们用一个新字符串来得到
                var remainingChar = string.Format("{0}/{1}", this.Text.Length, this.MaxLength);

                this.remainingCharacters.Text = remainingChar;

                //这句是没用
                this.remainingCharacters.Visibility = this.MaxLength > 0 ? Visibility.Visible : Visibility.Collapsed;
            }
        }

上面是大神写的,我建议可以简单一点。

        private void UpdateRemainingCharacters()
        {
            if (remainingCharacters != null)
            {
                if (MaxLength == 0)
                {
                    remainingCharacters.Visibility = Visibility.Collapsed;
                    return;
                }
                int length = 0;
                if (!string.IsNullOrEmpty(Text))
                {
                    length = Text.Length;
                }
                var remainingChar = string.Format("{0}/{1}", length, MaxLength);

                remainingCharacters.Text = remainingChar;

                //The above has judge the MaxLength ,and if it's 0,the Visibility will Collapsed
                //上面代码有判断MaxLength,如果是0,隐藏
                //this.remainingCharacters.Visibility = this.MaxLength > 0 ? Visibility.Visible : Visibility.Collapsed;
            }
        }

是否要检查

我们先判断是否要检查,如果不要检查,那么就返回对

return !IsMandatory;

如果要检查,我们的输入是空,我们要提示用户输入

            if (!this.IsMandatory && string.IsNullOrWhiteSpace(this.Text))
            {
                ValidationTextBlock.Text = this.MandatoryValidationMessage;
            }

ValidationTextBlock就是提示

我们判断,如果输入不是空,就返回,规则判断。

于是我们改为 如果不检查或输入是不空的,返回true,继续规则

如果检查并输入空,我们继续

输入空,我们提示

ValidationTextBlock.Text = this.MandatoryValidationMessage;

总的

        public bool IsMandatoryFieldValid()
        {
            //不检查 || 输入不是空
            //如果不检查,true
            //如果检查 如果输入不是空 true
            if (!this.IsMandatory || !string.IsNullOrWhiteSpace(this.Text))
            {
                return true;
            }

            if (this.ValidationTextBlock != null)
            {
                this.ValidationTextBlock.Text = this.MandatoryValidationMessage;
            }

            VisualStateManager.GoToState(this, "Mandatory", true);
            return false;
        }

长度

我们通过检查验证,我们继续

这时我们可以检查长度 Text.Length > this.MaxLength 如果大于长度,不通过

            bool[] isInvalid = { !this.IsMandatoryFieldValid() };

            if (!isInvalid[0])
            {
                if (this.MaxLength > 0)
                {
                    isInvalid[0] = this.Text.Length > this.MaxLength;
                }

                if (isInvalid[0])
                {
                    if (this.ValidationTextBlock != null)
                    {
                        this.ValidationTextBlock.Text = "The text exceeds the maximum length.";
                    }
                }
            }    //不知道isInvalid 

判断

如果输入长度不大于最大,我们判断是否符合要求

                    if (ValidationRules != null)
                    {
                        foreach (var temp in ValidationRules.Rules)
                        {
                            isInvalid[0] = !temp.IsValid(Text);
                            if (isInvalid[0] && ValidationTextBlock != null)
                            {
                                ValidationTextBlock.Text = temp.ErrorMessage;
                                break;
                            }
                        }
                    }

大神写的使用TakeWhile,这判断符合条件,如果符合,返回

           if (!isInvalid[0])
            {
                if (this.MaxLength > 0)
                {
                    isInvalid[0] = this.Text.Length > this.MaxLength;
                }

                if (isInvalid[0])
                {
                    if (this.ValidationTextBlock != null)
                    {
                        this.ValidationTextBlock.Text = "The text exceeds the maximum length.";
                    }
                }
                else
                {
                    if (this.ValidationRules != null)
                    {
                        // Run through all of the validation rules for this text box and check is valid.
                        foreach (var rule in this.ValidationRules.Rules.TakeWhile(rule => !isInvalid[0]))
                        {
                            isInvalid[0] = !rule.IsValid(this.Text);

                            if (isInvalid[0] && this.ValidationTextBlock != null)
                            {
                                this.ValidationTextBlock.Text = rule.ErrorMessage;
                            }
                        }
                    }

                    //if (ValidationRules != null)
                    //{
                    //    foreach (var temp in ValidationRules.Rules)
                    //    {
                    //        isInvalid[0] = !temp.IsValid(Text);
                    //        if (isInvalid[0] && ValidationTextBlock != null)
                    //        {
                    //            ValidationTextBlock.Text = temp.ErrorMessage;
                    //            break;
                    //        }
                    //    }
                    //}
                }
            }

我们需要把判断放到IsInvalid,IsInvalid = isInvalid[0];

我们把上面写的做函数,输入改变我们使用

        private void OnTextChanged(object sender, TextChangedEventArgs args)
        {
            this.Update();
        }

如何写检查

我们的核心就是它,我们需要一个类来放用户写的检查

这类我就放public List<ValidationRule> Rules { get; private set; }

开始核心ValidationRule,我们有很多检查,我们需要一个ValidationRule,定义的检查都可以修改ValidationRule新检查

ValidationRule只有一个属性,错误显示的Message

        private string _errorMessage;

        public string ErrorMessage
        {
            set
            {
                this._errorMessage = value;
            }
            get
            {
                return string.IsNullOrWhiteSpace(this._errorMessage) ? "Field invalid." : this._errorMessage;
            }
        }

其实如果_errorMessage不存在,我们要返回默认的,不要返回”Field invalid.”

        /// <summary>
        /// If the errorMessage is null  
        /// return DefaultErrorMessage
        /// </summary>
        public static string DefaultErrorMessage
        {
            set;
            get;
        } = "Field invalid.";

        private string _errorMessage;

        /// <summary>
        /// Gets the error message to display for the rule.
        /// </summary>
        public string ErrorMessage
        {
            set
            {
                this._errorMessage = value;
            }
            get
            {
                return string.IsNullOrWhiteSpace(this._errorMessage) ? DefaultErrorMessage : this._errorMessage;
            }
        }

然后就是一个函数,判断是否通过

public abstract bool IsValid(object value);

然后我们可以开始做检查

如DateTime

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return false;
            }

            var val = value.ToString();
            if (string.IsNullOrWhiteSpace(val))
            {
                return true;
            }

            DateTime temp;
            return DateTime.TryParse(val, out temp);
        }

decimal

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return false;
            }

            var val = value.ToString();
            if (string.IsNullOrWhiteSpace(val))
            {
                return true;
            }

            decimal temp;
            return decimal.TryParse(val, out temp);
        }

用户控件

<!-- &#19981;&#30693;Customer Control&#21483;&#29992;&#25143;&#25511;&#20214;&#65311;&#19981;&#24819;&#26597;&#65292;&#22823;&#23478;&#30693;&#36947;&#25105;&#35828;&#20160;&#20040;&#23601;&#22909; -->

我们使用继承TextBox做自己的控件

public partial class ValidatingTextBox : TextBox

我们上面用了remainingCharacters ValidationTextBlock 我们需要把它显示

我们告诉后来写ControlTemplate 我们要remainingCharactersTextBlock ValidationTextBlock,我们给他名字 RemainingCharacters,ValidationText 我们就可以在OnApplyTemplate

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.remainingCharacters = this.GetTemplateChild("RemainingCharacters") as TextBlock;
            this.ValidationTextBlock = this.GetTemplateChild("ValidationText") as TextBlock;
        }    

但我们需在ValidatingTextBox

    [TemplatePart(Name = "ValidationText", Type = typeof(TextBlock))]
    [TemplatePart(Name = "RemainingCharacters", Type = typeof(TextBlock))]

垃圾wr做这是做界面的人和做逻辑可以两个人,做界面只要知道有那些控件就好
TemplatePart是告诉做界面,我的需要名字为Name,类型为什么的控件,你要做前台写这个控件。

我们还需加事件

       protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.remainingCharacters = this.GetTemplateChild("RemainingCharacters") as TextBlock;
            this.ValidationTextBlock = this.GetTemplateChild("ValidationText") as TextBlock;

            this.Update();

            if (!this.IsTemplateApplied)
            {
                this.TextChanged += this.OnTextChanged;
                this.IsEnabledChanged += this.OnIsEnabledChanged;

                this.IsTemplateApplied = true;
            }
        }

我们设Style,没有Key,所有的控件都使用我们写的Style

我们新建一个资源,只要里面有<Style TargetType="controls:ValidatingTextBox">

我们用新建副本,直接复制TextBox的Style,不需要做什么修改。

我们在下面,修改显示

我们需要一个Head、一个显示字符数、一个验证,TextBlock

但是还记得我们约定,需要显示字符数的名字RemainingCharacters,显示验证名字ValidationText

于是我们使用布局,直接放TextBlock,于是我们的控件做好。

有一些比较难说我没有说,请去看代码 http://git.oschina.net/lindexi/WinUX-UWP-Toolkit

本文:http://lindexi.oschina.io/lindexi/post/win10-uwp-%E9%AA%8C%E8%AF%81%E8%BE%93%E5%85%A5-%E8%87%AA%E5%AE%9A%E4%B9%89%E7%94%A8%E6%88%B7%E6%8E%A7%E4%BB%B6/

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
分享到:
评论

相关推荐

    MVVM自定义用户控件

    创建自定义用户控件意味着我们需要扩展WPF或UWP的基础控件,以满足特定的需求或提供独特的功能。以下是创建自定义用户控件的步骤: 1. **定义控件类**:在C#中,创建一个新的类,继承自`System.Windows.Controls....

    自定义Tabpage控件,tabcontrol控件,很漂亮哦,C#源代码

    在Windows应用程序开发中,TabControl控件是一个非常常用且功能强大的组件,它允许用户通过不同的页面(TabPage)来组织和切换内容。...同时,这也为其他高级主题,如WPF或UWP中的控件自定义提供了基础。

    UWP-master:UWP自定义控件

    7. **XAML语法**:XAML是一种用于声明式地构建用户界面的语言,它是创建UWP自定义控件的主要工具。学习如何在XAML中声明控件、属性和事件,以及如何嵌入代码-behind,是创建自定义控件的基础。 8. **VisualState...

    Win10 UWP 开发教程 课程 资源

    Win10 UWP 开发教程 课程 资源 80课时 课程地址:http://blog.csdn.net/shanguuncle/article/details/78111649

    Win10 UWP应用代理工具

    全选设置之后UWP即可访问localhost,可以走代理。

    为Silverlight创建自定义控件

    在本文中,我们将深入探讨如何在Silverlight 2中创建自定义控件,这是一个关键的开发技能,可以让你根据特定需求扩展和定制UI组件。Silverlight的控件模型提供了丰富的可扩展性,允许开发者构建高度专业化和交互性的...

    Win10下通过UWP刷新WIFI

    下面我们将深入探讨如何在Win10下通过UWP实现这些功能。 首先,我们需要了解UWP(Universal Windows Platform)是微软为Windows 10推出的一种跨设备的应用程序开发框架。它允许开发者编写一次代码,就能在各种...

    win10 uwp 轻量级 MVVM 框架入门 2.1.5.3199 例子

    总结来说,"win10 uwp 轻量级 MVVM 框架入门 2.1.5.3199 例子"提供了一个实际操作的平台,让开发者学习如何在UWP环境中利用MVVM模式进行开发。通过分析和实践这个框架,你将能够更好地理解MVVM的工作原理,以及如何...

    C#实现win10 uwp 右击浮出窗在点击位置

    在Windows 10 UWP应用开发中,常常需要创建一种用户友好的交互方式,即当用户右键点击某个元素时,能在一个特定的位置显示一个浮出菜单(MenuFlyout)。本篇文章将详细介绍如何使用C#实现这样的功能,使得MenuFlyout...

    CustomControls_thyjcd_自定义控件_

    自定义控件允许开发者根据特定需求扩展或修改内置的UI元素,以实现独特的用户界面功能。在标题"CustomControls_thyjcd_自定义控件_"中,我们可以推断这是一个关于自定义控件的资源集合,可能包含了代码示例、教程...

    win10 uwp 使用 asp dotnet core 做图床服务器客户端

    在本文中,我们将探讨如何利用Windows 10的UWP(通用Windows平台)应用程序与ASP.NET Core构建一个图床服务器的客户端。这是一个涉及到跨平台开发和云端图像存储管理的项目,旨在提供一种高效且灵活的方式来上传和...

    自定义控件

    自定义控件允许开发者根据需求创建具有独特外观和功能的界面元素,从而提升应用程序的用户体验和视觉吸引力。本资源包名为"C#自定义控件库",显然聚焦于C#编程语言中的自定义控件开发技术。 C#是一种广泛应用于...

    用户控件-2018.zip

    可能包含了当年流行的设计模式、最佳实践,或者是对当时新特性的探索,比如.NET Framework 4.7的新功能,或是Windows 10 UWP平台上的用户控件开发技术。 "a.txt"文件可能包含有关用户控件的笔记、代码片段、提示或...

    win10 moblie uwp qq5.6.1150.1000

    win10 moblie uwp qq5.6.1150.1000主程序,不含依赖程序

    win10 moblie uwp 越飞阅读1.4.68.0

    win10 moblie uwp 越飞阅读1.4.68.0主程序,不含依赖程序

    自定义textbox完整工程

    此外,自定义控件不仅限于Windows Forms,对于WPF、UWP等其他UI框架也有类似的概念,只是实现方式会有所不同。理解并掌握自定义控件的开发,将有助于我们更好地适应各种开发环境,提高软件的可定制性和用户体验。 ...

    lindexi#lindexi#2020-10-28-win10-uwp-字符文本转语音声音文件方法1

    title: "win10 uwp 字符文本转语音声音文件方法"在 UWP 中,支持将传入的字符串文本内容转换为音频语音,可以将这个语音声音通过 MediaEl

    Python-微软已经引入了一项开源UWP社区工具包帮助开发者通过Win10SDK进行互相合作

    微软推出的开源UWP社区工具包(Windows Community Toolkit)是一个关键的资源,它旨在简化和加速开发流程,使得开发者能够更高效地利用Win10 SDK进行编程。 UWP社区工具包是一个集合了各种辅助工具、组件和示例代码...

    lindexi#lindexi#2019-09-02-win10-uwp-随着数字变化颜色控件1

    我朋友在做一个控件,是显示异常,那么异常多就变为颜色,大概就是下面的图,很简单首先是一个Ellipse,然后把他的颜色绑定到Int,需要一个转换,UWP的转换和

    博客园UWP源码

    这次纯当练手入门,公司也不做win10这方面的东西,以后业余可以多搞搞。 体验: 1)win10开发感觉不错,PC的源码拿到手机上只需要调整界面,其他代码 几乎 可以不用改动。有想法的可以赶紧行动起来; 2)多用异步...

Global site tag (gtag.js) - Google Analytics