从特定上下文启动ExceptionValidationRule

本文关键字:启动 ExceptionValidationRule 上下文 | 更新日期: 2023-09-27 18:09:53

我有一个类客户端:

public class Client : INotifyPropertyChanged
{
    private string m_strCode;
    public string strCode
    {
        get { return m_strCode; }
        set
        {
            if (CodeIsValide(strCode))
            {                  
                m_strCode = value;
                FirePropertyChangedEvent("strCode");
            }
            else
            {
                throw new ApplicationException("bad Data !");
            }
            FirePropertyChangedEvent("strCode");
        }
    }
    private string m_strName;
    public string strName
    {
        get { return m_strName; }
        set
        {
            if (NameIsValide(strName))
            {
                m_strName = value;
                FirePropertyChangedEvent("strName");
            }
            else
            {
                throw new ApplicationException("Bad Data! ");
            }
            FirePropertyChangedEvent("strName");
        }
    }
    public Client(string Code, string Name)
    {
        strCode = Code;
        strName = Name;
    }
    public Client()
    {
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void FirePropertyChangedEvent(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

在我的WPF窗口上,我有两个文本框:一个用于client.strCode,另一个用于client.strNom.

这是XAML:

<TextBox x:Name="TextBox_Code"
         HorizontalAlignment="Left"
         Height="25"
         Margin="106,230,0,0"
         TextWrapping="Wrap"
         VerticalAlignment="Top"
         Width="78">
  <TextBox.Text>
    <Binding Path="strCode"
             UpdateSourceTrigger="PropertyChanged">
      <Binding.ValidationRules>
        <ExceptionValidationRule />
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>
<TextBox x:Name="TextBox_Name"
         HorizontalAlignment="Left"
         Height="25"
         Margin="106,230,0,0"
         TextWrapping="Wrap"
         VerticalAlignment="Top"
         Width="78">
  <TextBox.Text>
    <Binding Path="strName"
             UpdateSourceTrigger="PropertyChanged">
      <Binding.ValidationRules>
        <ExceptionValidationRule />
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>

数据输入正在使用ValidationProcess进行验证。如果验证为false,则在文本框附近会显示一个警告标签。

我的问题是:如果我将坏数据(从数据库(加载到客户端对象的集合。加载使用我的strCode和strName的set((,如果数据不正确,则不能抛出ExceptionValidationRule(我认为这是因为ExceptionValidation Rule不是从绑定的文本框中调用的(。(我不是英国人,对不起,这不足以解释(。

我想我需要指定何时调用verifiy进程。

有人有什么建议吗?

如果有人愿意的话,我创建一个VS项目示例来分享我的问题。

编辑:如果我使用自定义验证程序类,那没问题!

只是一个问题,为了强制进行验证测试,当我在DataGrid:中选择行时,我需要这样做

    private void myDataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
    {
        // Affiche le code évt sélectionné dans le tableau, dans les champs modifiable ( en haut de l'écran )
        var item = myDataGrid.SelectedItem as Client;
        if ((item != null))
        {
            TextBox_Code.Text = item.strCode;
            TextBox_Name.Text = item.strName;
        }
    }

TextBox_Code.Text = item.strCode;
TextBox_Name.Text = item.strName;

如果我删除这两行,由于绑定,文本框被正确初始化,但验证过程不会被调用。为什么?有没有一种方法可以强制验证过程并使用完全绑定精简:

TextBox_Code.Text = item.strCode;
TextBox_Name.Text = item.strName;

谢谢:(

非常感谢:(

致问候,

Nixeus:(

从特定上下文启动ExceptionValidationRule

如果我正确理解您的要求,

如果属性是从xaml视图以外的任何对象设置的,则不希望引发异常。

我的首选解决方案是完全不使用ExceptionValidationRule,而更喜欢自定义ValidationRule。这将解决您的问题。示例显示了如何创建和使用这样的功能。

自定义验证规则示例:

public class CodeRangeRule : ValidationRule {
  public override ValidationResult Validate(object value, CultureInfo cultureInfo) {
    int strCode = -1;
    if (value != null && !Int32.TryParse(value.ToString(), out strCode))
      return new ValidationResult(false, "Illegal strCode");
    if (strCode < 9999 && strCode > 0) // Modify to suit your Validity Conditions
      return new ValidationResult(true, null);
    return new ValidationResult(false, "strCode is not within acceptable code range");
  }
}

和你的xaml:

<TextBox x:Name="TextBox_Code" HorizontalAlignment="Left" Height="25" Margin="106,230,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="78">
    <TextBox.Text>
        <Binding Path="strCode"  UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:CodeRangeRule />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

如果出于任何原因不想使用自定义ValidationRule,您可以保持ExceptionValidationRule在您的视图中的状态,并在从数据库加载或中调用setter之前添加一个try-catch

public class Client : INotifyPropertyChanged

添加另一个属性(比如值为kDatabaseLoadkView的枚举(,以指示视图/数据库是否处理该对象。因此,在抛出异常之前,在strCodestrName的setter中检查此枚举是否为kView

现在,当您加载数据库并创建Client对象时,在设置strNamestrCode之前,将其枚举分配给kDatabaseLoad。确保加载完成后将枚举切换回kView