向所有文本框添加自定义验证规则的简单方法 [英] simple way to add a custom validation rule to all textboxes

查看:161
本文介绍了向所有文本框添加自定义验证规则的简单方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在为页面中的所有文本框设置自定义验证规则时遇到问题.

I'm having problems setting a custom validation rule for all my textboxes in a Page.

我知道如何为1个单个文本框设置它:

I know how to set it for 1 single textbox:

<TextBox Margin="79,118,79,121" Name="textBox1" Style="{Binding EmptyTextboxValidator, UpdateSourceTrigger=PropertyChanged}">
    <TextBox.Text>
        <Binding Path="Text" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <validators:StringRangeValidationRule MinimumLength="1" ErrorMessage="Text is te kort" />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

但是,如果我需要为每个单独的文本框添加此代码,我不确定这是否有用,因为它将大量复制粘贴.必须有一种更简单的方法对吗?

However, if i need to add this code for every single textbox i'm not sure this is as useful since it would be an awful lot of copy pasting. There must be an easier way right?

如果进行了大量搜索,但是我找不到为所有文本框设置示例的示例,只有为1个单个文本框设置示例的示例(如上所示)

if been doing a lot of searching but i couldn't find an example to set it for all textboxes, only examples to set it for 1 single textbox (as shown above)

以下是文本框样式的代码:

here's the code for the textbox style:

<Application.Resources>
    <Style x:Key="EmptyTextboxValidator" TargetType="{x:Type TextBox}">
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel LastChildFill="True">
                        <Border BorderBrush="Red" BorderThickness="3">
                            <AdornedElementPlaceholder Name="MyAdorner" />
                        </Border>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <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>
</Application.Resources>

以及验证规则的代码:

using System;
using System.Windows.Controls;
using System.Globalization;

namespace MyValidators
{
    public class StringRangeValidationRule : ValidationRule
    {
        private int _minimumLength = 1;
        private string _errorMessage;

        public int MinimumLength
        {
            get { return _minimumLength; }
            set { _minimumLength = value; }
        }

        public string ErrorMessage
        {
            get { return _errorMessage; }
            set { _errorMessage = value; }
        }

        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            ValidationResult result = new ValidationResult(true, null);
            string inputString = (value ?? string.Empty).ToString();
            if (string.IsNullOrEmpty(inputString) || inputString.Length < MinimumLength)
            {
                result = new ValidationResult(false, this.ErrorMessage);
            }
            return result;
        }
    }
}

viewModel:

the viewModel:

public class Data : INotifyPropertyChanged
{
    private int id = -1;
    private bool updated = true;
    private string text;
    private string name;

    public int ID
    {
        get
        {
            return id;
        }
        set
        {
            id = value;
            OnPropertyChanged("ID");
        }
    }

    public bool Updated
    {
        get
        {
            return updated;
        }
        set
        {
            updated = value;
        }
    }

    public string Text
    {
        get
        {
            return text;
        }
        set
        {
            text = value;
            OnPropertyChanged("Text");
        }
    }

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

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        updated = true;
    }
    #endregion
}

我对xaml的了解也很有限,并且该代码是我为获得对xaml的更多理解而进行的测试的一部分.

Also my knowledge of xaml is limited and this code was part of a test i made to get some more understanding of xaml.

例如,也许还有一种方法可以只将字段添加到文本框中:

Also might there be a way to just add field to the textbox for example:

<TextBox ValidateStringLength="true"/>

甚至更好,如果我可以给它一个整数参数以表示字符串的最小长度:

or even better if i could just give it an integer parameter for the minimum length of the string:

<TextBox ValidateStringLength="5"/>

无论是2之一(将其设置为我正在执行的操作,但要同时为所有文本框设置)或上面演示的示例,我们都将不胜感激.

Either one of the 2 (setting it as i'm doing but for all textboxes at once) or the example i demonstrated above would be really appreciated.

推荐答案

该解决方案称为BindingGroup.看一下这段代码:

The solution is called BindingGroup. Take a look at this code:

<StackPanel Name="stackPanel1">
  <StackPanel.BindingGroup>
    <BindingGroup NotifyOnValidationError="True">
      <BindingGroup.ValidationRules>
        <src:ValidateDateAndPrice ValidationStep="ConvertedProposedValue" />
      </BindingGroup.ValidationRules>
    </BindingGroup>
  </StackPanel.BindingGroup>

  <HeaderedContentControl Header="Price">
    <TextBox Name="priceField"  Width="150">
      <TextBox.Text>
        <Binding Path="Price" Mode="TwoWay" />
      </TextBox.Text>
    </TextBox>
  </HeaderedContentControl>

  <HeaderedContentControl Header="Date Offer Ends">
    <TextBox Name="dateField" Width="150" >
      <TextBox.Text>
        <Binding Path="OfferExpires" StringFormat="d" />
      </TextBox.Text>
    </TextBox>
  </HeaderedContentControl>

  <StackPanel Orientation="Horizontal">
    <Button IsDefault="True" Click="Submit_Click">_Submit</Button>
    <Button IsCancel="True" Click="Cancel_Click">_Cancel</Button>
  </StackPanel>
</StackPanel>

所有文本框都有ValidateDateAndPrice ValidationRule可用.

All the TextBoxes have ValidateDateAndPrice ValidationRule available.

您还可以控制何时保存更改.

And you can also control when changes shall be saved.

private void Submit_Click(object sender, RoutedEventArgs e)
{
    if (stackPanel1.BindingGroup.CommitEdit())
    {
        MessageBox.Show("Item submitted");
        stackPanel1.BindingGroup.SubmitEdit();
    }
}

在这种情况下,单击按钮将提交更改.

In this case changes are being submitted when button clicked.

我将为您举例说明如何使其工作.我用您的代码创建了示例.

I will give you an example how to make it work. I used your code to create the example.

<Window>
    ....
    <Window.Resources>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <DockPanel LastChildFill="True">
                            <Border BorderBrush="Blue" BorderThickness="3">
                                <AdornedElementPlaceholder Name="MyAdorner" />
                            </Border>
                        </DockPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <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>

    <Window.BindingGroup>
        <BindingGroup>
            <BindingGroup.ValidationRules>
                <local:StringRangeValidationRule MinimumLength="5" ErrorMessage="Text too long!" />
            </BindingGroup.ValidationRules>
        </BindingGroup>
    </Window.BindingGroup>

    <Grid Margin="10" >
        <TextBox Margin="100, 5, 0, 0" HorizontalAlignment="Left" VerticalAlignment="Top"
                 Text="{Binding Name}" Validation.ValidationAdornerSiteFor="{Binding ElementName=window}">
        </TextBox>
        <Button Content="Save" Click="Button_Click" Margin="0, 5, 100, 0" HorizontalAlignment="Right" VerticalAlignment="Top"/>
    </Grid>
</Window>

您需要在窗口中拥有模板和样式才能使其正常工作.

You need to have your templates and styles in window to make it work.

这是背后的代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new Data() { Name = "Hello World!" };
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        window.BindingGroup.CommitEdit();
    }
}

public class Data : INotifyPropertyChanged
{
    private int id = -1;
    private bool updated = true;
    private string text;
    private string name;

    public int ID
    {
        get
        {
            return id;
        }
        set
        {
            id = value;
            OnPropertyChanged("ID");
        }
    }

    public bool Updated
    {
        get
        {
            return updated;
        }
        set
        {
            updated = value;
        }
    }

    public string Text
    {
        get
        {
            return text;
        }
        set
        {
            text = value;
            OnPropertyChanged("Text");
        }
    }

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

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        updated = true;
    }

    #endregion
}

public class StringRangeValidationRule : ValidationRule
{
    private int _minimumLength = 1;
    private string _errorMessage;

    public int MinimumLength
    {
        get { return _minimumLength; }
        set { _minimumLength = value; }
    }

    public string ErrorMessage
    {
        get { return _errorMessage; }
        set { _errorMessage = value; }
    }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        BindingGroup group = (BindingGroup)value;
        var item = group.Items[0];
        string inputString = (group.GetValue(item, "Name") ?? string.Empty).ToString();
        if (true || string.IsNullOrEmpty(inputString) || inputString.Length < MinimumLength)
        {
            return new ValidationResult(false, this.ErrorMessage);
        }

        return ValidationResult.ValidResult;
    }
}

如您所见,我更改了验证规则,并添加了Validation.ValidationAdornerSiteFor以指示TextBox应该显示错误.

As you can see I changed the validation rule and I added Validation.ValidationAdornerSiteFor to indicate the TextBox should display error.

您应该能够复制并粘贴它,它将起作用.

You should be able to copy and paste this and it will work.

这篇关于向所有文本框添加自定义验证规则的简单方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆