WPF ErrorTemplate

//xaml
<Window x:Class="WpfApp91.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp91"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <ControlTemplate x:Key="errorTemplate">
            <Border BorderBrush="Red" BorderThickness="10">
                <Grid>
                    <AdornedElementPlaceholder x:Name="_el"/>
                    <TextBlock Text="{Binding [0].ErrorContent}"
                        Foreground="Red" HorizontalAlignment="Right"
                        VerticalAlignment="Center" Margin="0,0,6,0"/>
                </Grid>
            </Border>
        </ControlTemplate>
    </Window.Resources>
    <Grid TextBlock.FontSize="30">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBlock Text="Name:" Margin="6"/>
        <TextBox Grid.Column="1" Validation.ErrorTemplate="{StaticResource ResourceKey=errorTemplate}" >
            <TextBox.Text>
                <Binding Path="Name" ValidatesOnDataErrors="True"
                         UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <local:MinCharsRule MinimumChars="3"/>
                    </Binding.ValidationRules>
                </Binding> 
            </TextBox.Text> 
        </TextBox>
        <TextBlock Text="Age:" Grid.Row="1" Margin="6"/>
        <TextBox Text="{Binding Age,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, 
            ValidatesOnExceptions=True,ValidatesOnDataErrors=True}"  Grid.Column="1" Grid.Row="1" Margin="6"/>
    </Grid>
</Window>


//cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp91
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new Person
            {
                Name = "Fred",
                Age = 17
            };
        }
    }

    public class Person : INotifyPropertyChanged,IDataErrorInfo
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propName)
        {
            var handler = PropertyChanged;
            if(handler!=null)
            {
                handler?.Invoke(this,new PropertyChangedEventArgs(propName));
            }
        }

        private int age;
        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                if(value<1)
                {
                    throw new ArgumentException("Age must be a positive integer!");
                }
                if(value!=age)
                {
                    age = value;
                    OnPropertyChanged("Age");
                }
            }
        }

        private string name;
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                if (value!=name)
                {
                    name = value;
                    OnPropertyChanged("Name");
                }
            }
        }

        public string Error
        {
            get
            {
                return null;
            }
        }

        public string this[string columnName]
        {
            get
            {
                switch(name)
                {
                    case "Name":
                        if(string.IsNullOrWhiteSpace(Name))
                        {
                            return "Name cannot be empty!";
                        }
                        break;
                    case "Age":
                        if(Age<1)
                        {
                            return "Age must be a positive integer";
                        }
                        break;
                }
                return null;
            }
        }
    }

    class MinCharsRule : ValidationRule
    {
        public int MinimumChars { get; set; }
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            if(value?.ToString()?.Length< MinimumChars)
            {
                return new ValidationResult(false, "Use at least " + MinimumChars.ToString()
                    + " characters");
            }
            return new ValidationResult(true, null);
        }
    }
}

 

posted @ 2024-05-03 21:43  FredGrit  阅读(22)  评论(0编辑  收藏  举报