我有一个班级客户:
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窗口中,我有两个文本框:on用于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,则在文本框附近显示警告标签。
我的问题是:如果我将不良数据(从DataBase)加载到Collection of Client对象。加载使用我的strCode和strName的set(),如果数据不好,则不能抛出ExceptionValidationRule(我认为这是因为没有从绑定的文本框中调用ExceptionValidationRule)。 (我不是英国人,不能解释抱歉)。
我想我需要指定何时调用验证过程。
有人有建议吗?
如果有人想要,我创建一个示例VS项目以分享我的问题。
编辑:如果我使用自定义验证器类,那就OK了!
只是一个问题,为了强制进行验证测试,当我选择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;
如果删除这两行,则由于绑定而对文本框进行了核心初始化,但未调用验证过程。为什么?有没有办法强制验证过程并使用完整的绑定whitout:
TextBox_Code.Text = item.strCode;
TextBox_Name.Text = item.strName;
谢谢:)
非常感谢:)
致以最诚挚的问候,
Nixeus:)
答案 0 :(得分:1)
如果我理解你的要求是正确的,
如果属性是从xaml视图以外的任何地方设置的,那么您不希望引发异常。
我首选的解决方案是根本不使用ExceptionValidationRule
,而更喜欢自定义ValidationRule
。这将解决您的问题。 Example显示了如何创建和使用此功能。
自定义验证规则的示例:
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
添加另一个属性(比如带有值kDatabaseLoad
,kView
的枚举)以指示对象是否由View / Database处理。因此,在strCode
和strName
的设置器中,在抛出异常之前检查此枚举是否为kView
。
现在,当您执行数据库加载并创建Client
个对象时,请在设置kDatabaseLoad
和strName
之前将其枚举为strCode
。确保在完成加载后将枚举切换回kView
。