我正在尝试在2个datagrid列之间创建验证依赖项。
第一列是下拉框。 (DataGridTemplateColumn) 第二个是文本列。 (DataGridTextColumn)
我正在尝试从后面的代码中的下拉框事件强制验证同一行的datagrid文本列单元格。
感谢您的帮助。
<data:DataGridTemplateColumn Header="Type" >
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource TypeListContainer}, Path=TypeLists}" Loaded="TypeBoxLoaded" DropDownClosed="TypeBoxChanged">
</ComboBox>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
<data:DataGridTextColumn Header="Rule" Binding="{Binding RuleWrapper, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" x:Name="RuleCol" />
这是属性
public string RuleWrapper
{
get
{
return this.Rule;
}
set
{
//Required
if (value == null || value == string.Empty)
{
throw new ValidationException("Rule is required");
}
//Match regular expression if type is channel
Regex reg = new Regex(@"^(51[01]|50[0-9]|[0-4]?[0-9][0-9]?)\.(51[01]|50[0-9]|[0-4]?[0-9][0-9]?)\.(51[01]|50[0-9]|[0-4]?[0-9][0-9]?)\.(51[01]|50[0-9]|[0-4]?[0-9][0-9]?)$");
if (Type == "channel" && !reg.IsMatch(value))
throw new ValidationException("Channel not matching the right format");
//Match range if type is trunk
int intValue = -1;
//Match if is a number
if (int.TryParse(value, out intValue))
{
//Match if number is in the range
if (intValue < 0 || intValue > 134217727)
throw new ValidationException("Trunk value must be between 0 and 134317727");
}
else
throw new ValidationException("Trunk value must a an integer");
this.Rule = value;
}
}
答案 0 :(得分:2)
有几点需要注意(我还在学习验证,所以我有待纠正)。
WPF不支持 ValidationException 。
在仅绑定句柄中设置 ValidatesOnExceptions = True 内部使用的默认转换器中的异常(例如将字符串转换为 数)。
您自己的转换器中的异常未被捕获并导致您的应用 坠毁。
使用 IDataErrorInfo , INotifyDataErrorInfo(Silverlight和WPF 4.5)和 ValidationRule
处理验证此刻我正在回答WPF的观点。我稍后会测试Silverlight。
MSDN在这里有一篇非常好的文章关于binding and validation。
这是我的示例,它演示了两个文本列之间的验证依赖关系(为简单起见)。第二列是只读的,但显示由第一列引起的验证错误。
<Grid>
<Grid.DataContext>
<Samples:DataGridValidationViewModels/>
</Grid.DataContext>
<DataGrid AutoGenerateColumns="False" ItemsSource={Binding Items}>
<DataGrid.Columns>
<DataGridTextColumn Header="Column 1" Binding="{Binding Column1, ValidatesOnDataErrors=True}" />
<DataGridTextColumn IsReadOnly="True" Header="Column 2" Binding="{Binding Column2, ValidatesOnDataErrors=True}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
我正在使用MVVM Light作为我的视图模型/ INotifyPropertyChange支持,因此将 Set(()=&gt; ... 的使用替换为您自己的实现(_prop = value; RaisePropertyChanged( “string”);等)。
请注意,在只读属性上引发属性更改事件会导致在该属性上进行验证,这是有用的。
public class DataGridValidationViewModels
{
public DataGridValidationViewModels()
{
Items = new ObservableCollection<DataGridValidationViewModel>
{
new DataGridValidationViewModel(),
new DataGridValidationViewModel(),
new DataGridValidationViewModel(),
new DataGridValidationViewModel(),
new DataGridValidationViewModel(),
new DataGridValidationViewModel(),
new DataGridValidationViewModel(),
};
}
public IEnumerable<DataGridValidationViewModel> Items { get; set; }
}
public class DataGridValidationViewModel : ViewModelBase, IDataErrorInfo
{
public DataGridValidationViewModel()
{
_column1 = "Column 1";
_column2 = "Column 2";
}
private string _column1;
public string Column1
{
get { return _column1; }
set
{
Set(() => Column1, ref _column1, value);
Column2 = value;
}
}
private string _column2;
public string Column2
{
get { return _column2; }
private set{ Set(()=>Column2, ref _column2, value);}
}
#region Implementation of IDataErrorInfo
public string this[string columnName]
{
get
{
switch (columnName)
{
case "Column1":
return Column1 == "Error" ? "There's an error in column 1!" : string.Empty;
case "Column2":
return Column1 == "Error" ? "There's an error in column 2!" : string.Empty;
}
return string.Empty;
}
}
public string Error
{
get { return string.Empty; }
}
#endregion
}
当您将第1列的文本更改为“错误”时,您会得到: