WPF --- TextBox的輸入校驗

来源:https://www.cnblogs.com/pandefu/archive/2023/11/16/17837358.html
-Advertisement-
Play Games

引言 在WPF應用程式開發中,數據校驗是確保用戶輸入數據的正確性和完整性的重要一環。 之前在做一些參數配置功能時,最是頭疼各種參數校驗,查閱一些資料後,我總結了數據校驗方式有兩種: ValidationRule IDataErrorInfo 接下來分別介紹這兩種校驗方式。 ValidationRul ...


引言

在WPF應用程式開發中,數據校驗是確保用戶輸入數據的正確性和完整性的重要一環。

之前在做一些參數配置功能時,最是頭疼各種參數校驗,查閱一些資料後,我總結了數據校驗方式有兩種:

  • ValidationRule
  • IDataErrorInfo

接下來分別介紹這兩種校驗方式。

ValidationRule

ValidationRule 是一個抽象類,提供了抽象方法 Validate(), 它是WPF中用於數據驗證的一種機制,它可以在用戶輸入數據之前或之後執行自定義的驗證邏輯。可以輕鬆地實現對數據的格式、範圍、邏輯等方面的驗證,併在驗證失敗時提供相應的反饋信息。

ValidationRule主要作用域在前端頁面上

基本用法

首先創建一個 ValidationRule,我這裡設定了兩個屬性 MaxValMinVal,然後在 Validate() 方法中判斷空、判斷大於上限或小於下限,然後在符合條件是,返回 ValidationResult,並給出錯誤提示:

public class IntegerValidationRule : ValidationRule
{
    public int MaxVal { get; set; }
    public int MinVal { get; set; }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        string text = value as string;

        if (!int.TryParse(text, out int result))
        {
            return new ValidationResult(false, "Text cannot be empty.");
        }

        if (result > MaxVal)
        {
            return new ValidationResult(false, "Value out of upper limit range.");
        }

        if (result < MinVal)
        {
            return new ValidationResult(false, "Value out of lower limit range.");
        }

        return ValidationResult.ValidResult;
    }
}

接下來創建有個測試使用的 ViewModel:

public class TestViewModel : INotifyPropertyChanged
{
    private TestViewModel() { }

    public static TestViewModel Instance { get; } = new TestViewModel();

    public event PropertyChangedEventHandler? PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private int testField1;
    /// <summary>
    /// 測試屬性1
    /// </summary>
    public int TestField1
    {
        get => testField1;
        set
        {
            testField1 = value;
            OnPropertyChanged(nameof(TestField1));
        }
    }

    private int testField2;
    /// <summary>
    /// 測試屬性2
    /// </summary>
    public int TestField2
    {
        get => testField2;
        set
        {
            testField2 = value;
            OnPropertyChanged(nameof(TestField2));
        }
    }
}


在測試之前,我們可以先看一下 Binding 的方法列表:

image.png

可以看到 ValidationRulesBinding 下的集合,這意味著 ValidationRule 是在 Binding 下使用且可以執行多個校驗規則。校驗時按照順序依次校驗。

接下來我們創建一個WPF應用程式,在界面添加 TextBox,命名為”textbox1“,將文本綁定在 TestViewModelTestField1

且為Validation.ErrorTemplate 綁定一個模板,這裡綁定了一個紅色的感嘆號。

然後為 TextBox 設置觸發器,當 Validation.HasErrortrue時,將 ToolTip 綁定校驗失敗的錯誤提示。

代碼如下:

<Window
    x:Class="WpfApp4.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:local="clr-namespace:WpfApp4"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="900"
    Height="450"
    mc:Ignorable="d">
    <Window.Resources>
        <ControlTemplate x:Key="ValidationTemplate">
            <DockPanel>
                <TextBlock
                    Margin="-10,0,0,0"
                    VerticalAlignment="Center"
                    FontSize="22"
                    Foreground="Red"
                    Text="!" />

            </DockPanel>
        </ControlTemplate>

        <Style TargetType="TextBox">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Column="0">
            <TextBlock
                HorizontalAlignment="Center"
                FontSize="18"
                FontWeight="Bold"
                Text="Validation Demo" />
            <TextBox
                Name="textBox1"
                Height="30"
                Margin="10"
                FontSize="22"
                Validation.ErrorTemplate="{StaticResource ValidationTemplate}">
                <TextBox.Text>
                    <Binding Path="TestField1" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <local:IntegerValidationRule
                                MaxVal="999"
                                MinVal="5" />
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>

        </StackPanel>
    </Grid>
</Window>

最後在窗體後臺綁定 ViewModel:

public MainWindow()
{
    InitializeComponent();
    this.DataContext =  TestViewModel.Instance;
}

測試

  1. 為空時,出現紅色嘆號,ToolTip 提示 "Text cannot be empty."
    image.png

  2. 小於下限時,出現紅色嘆號,ToolTip 提示 "Value out of lower limit range."
    image.png

  3. 大於上限時,出現紅色嘆號,ToolTip 提示 "Value out of upper limit range."
    image.png

IDataErrorInfo

IDataErrorInfo 是一個介面,Viewmodel 實現介面用於在後臺,提供數據驗證和錯誤信息。

IDataErrorInfo 主要作用域為後臺 ViewModel
該介面包含兩個成員:Errorthis[string columnName]。這兩個成員允許你在數據綁定時提供驗證錯誤信息。

基本用法

接下來,在程式里添加 TextBox,命名為”textbox2“,並添加一個 TextBlock 綁定 Error 展示在界面。

<StackPanel Grid.Column="1">
    <TextBlock
        HorizontalAlignment="Center"
        FontSize="18"
        FontWeight="Bold"
        Text="IDataErrorInfo Demo" />
    <TextBox
        Name="textBox2"
        Margin="10"
        VerticalAlignment="Center"
        FontSize="22"
        Text="{Binding TestField2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
     <TextBlock
         HorizontalAlignment="Center"
         FontSize="18"
         FontWeight="Bold"
         Foreground="Red"
         Text="{Binding Error, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>

後臺 TestViweModel 實現 IDataErrorInfo,依舊是判斷上限值和下限值,此處不判斷空,是因為後臺 TestField2 類型是Int,為空時不會賦值,代碼如下:

public class TestViewModel : INotifyPropertyChanged, IDataErrorInfo
{
    //省略上文已有代碼..。
    
    private string error;
    public string Error
    {
        get => error;
        set
        {
            error = value; OnPropertyChanged(nameof(Error));
        }
    }
    public string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case nameof(TestField2):
                    return CheckTestFild2();
                default:
                    return null;
            }
        }
    }

    public int MaxVal = 999;
    public int MinVal = 5;

    private string CheckTestFild2()
    {
        if (TestField2 > MaxVal)
        {
            Error = "Value out of upper limit range in viewmodel.";
        }
        else if (TestField2 < MinVal)
        {
            Error = "Value out of lower limit range  in viewmodel.";
        }
        else
        {
            Error = string.Empty;
        }
        
        return Error;
    }
}

測試

  1. 小於下限時,出現紅色文字提示,ToolTip 提示 "Value out of lower limit range in viewmodel."
    image.png

  2. 大於上限時,出現紅色文字提示,ToolTip 提示 "Value out of upper limit range in viewmodel."
    image.png

小結

以上兩種數據校驗(IDataErrorInfoValidationRule)的方式,均可以實現自定義數據校驗,例如對數據的格式、範圍、邏輯等方面的驗證,併在驗證失敗時提供相應的反饋信息。

ValidationRule適用於在界面做數據校驗,且可以定義多個校驗規則。

ValidationRule適用於在ViewModel做數據校驗,可以做一些無法在前端頁面做的事情,比如出現異常值是還原為預設值。

所以兩者既可以單獨使用,也可以組合使用,即使使用MVVM模式,依舊能夠優雅的做數據校驗。

作者: Niuery Daily

出處: https://www.cnblogs.com/pandefu/>

郵箱: [email protected]

關於作者:.Net Framework,.Net Core ,WindowsForm,WPF ,控制項庫,多線程

本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出 原文鏈接,否則保留追究法律責任的權利。 如有問題, 可郵件咨詢。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 將Excel文件轉換為PDF可以方便儲存表格數據,此外在列印或共用文檔時也能確保表格樣式佈局等在不同設備和操作系統上保持一致。今天給大家分享一個使用第三方Python庫Spire.XLS for Python 實現Excel轉PDF的簡單方法。 Python中Excel轉PDF的實現步驟 1. 首先 ...
  • golang 的 map 使用的是 hash map 基本結構 下麵截取自源碼,已翻譯 // runtime/map.go:117 // go map 定義,hashmap 縮寫 type hmap struct { count int // map 里文件數 flags uint8 // map ...
  • 二叉樹初步: 代碼如下,註釋很詳細。 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> #include <stdlib.h> #include <stdio.h> #include <math.h> #in ...
  • 如何用Java設計自動售貨機?是大多在高級Java開發人員面試中經常被問到的好問題之一。在典型的編碼面試中,你會得到一個問題描述來開發一個售貨機,在有限的時間內,通常2到3小時內,你需要在Java中編寫設計文檔、工作代碼和單元測試。這種Java面試的一個關鍵優勢是可以一次測試候選人的許多基本技能。為 ...
  • 公眾號「架構成長指南」,專註於生產實踐、雲原生、分散式系統、大數據技術分享。 在之前的幾個教程中,我們學了: 使用 RestTemplate 的 Spring Boot 微服務通信示例 使用 WebClient 的 Spring Boot 微服務通信示例 使用 Spring Cloud Open F ...
  • 學習視頻:【孫哥說Spring5:從設計模式到基本應用到應用級底層分析,一次深入淺出的Spring全探索。學不會Spring?只因你未遇見孫哥】 第七章、反轉控制與依賴註入 1.反轉(轉移)控制(IOC inverse of Control) 控制:對於成員變數賦值的控制權 反轉控制:把對於成員變數 ...
  • 在Java中創建多線程,往往都要通過Thread類來實現,今天學習下Java中創建多線程的三種方法[1]。 1.繼承Thread類 通過繼承 Thread類 實現多線程。 主要方法: 1.void run(), 線程開啟後,方法將被調用執行 2.void start(), 使此線程開始執行, Jav ...
  • Scipy的ODR正交距離回歸(ODR-Orthogonal Distance Regression)模塊,適用於回歸分析時,因變數和自變數之間存在非線性關係的情況。它提高了回歸分析的準確性和穩健性。對於需要解決非線性回歸問題的科研人員和工程師來說,它具有非常重要的意義。 ODR正交距離回歸模塊的作 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...