如何获取WPF的DataGrid控件中,是否存在没有通过错误验证的Cell

粗暴的香蕉 2011-05-21 06:28:15
在WPF使用DataGrid从数据库中读取数据给用户编辑,编辑完后触发验证,如果例如验证输入的值一定要是整数。
验证失败会设置该Cell的样式以提示用户,并且该Cell一直处于编辑状态,并且不能对其他Cell进行编辑。
以上功能通过下面的XAML实现了
<DataGridTextColumn Header="区间通过时间" Binding="{Binding itv_time, ValidatesOnExceptions=True}" EditingElementStyle="{StaticResource cellErrorStyle}" 
Width="Auto" CanUserResize="False"></DataGridTextColumn>


现在的问题是,窗口中同时有一个提交的按钮,在存在没有通过验证的Cell时,用户仍然是可以点击那个提交按钮的,这样会把错误的数据提交上去。
想实现的是在点击提交按钮的时候,能够根据DataGrid是否有存在没有通过验证的Cell,有就取消提交操作,直至DataGrid中所有的数据都是通过验证的才能执行提交。
请问应该怎么做?
...全文
521 5 打赏 收藏 举报
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
Apenghui919 2011-12-20
你好!
在WPF使用DataGrid从数据库中读取数据给用户编辑,编辑完后触发验证,如果例如验证输入的值一定要是整数。
验证失败会设置该Cell的样式以提示用户,并且该Cell一直处于编辑状态,并且不能对其他Cell进行编辑。

你做的验证是ValidatesOnExceptions ,基于异常的,如果改成ValidatesOnDataErrors 这是基于实现IDataErrorInfo接口的。就实现不了C该ell一直处于编辑状态,并且不能对其他Cell进行编辑
  • 打赏
  • 举报
回复
wangye2008 2011-10-22

/// <summary>
/// 获取DataGrid的所有行是否存在验证错误。
/// </summary>
/// <param name="dg">要检查的DataGrid实例</param>
/// <returns>true 有错,false 无错</returns>
public static bool GetDataGridRowsHasError(DataGrid dg)
{
bool hasError = false ;
for (int i = 0; i < dg.Items.Count; i++)
{
DependencyObject o = dg.ItemContainerGenerator.ContainerFromIndex(i);
hasError = Validation.GetHasError(o);
if (hasError)
{
break;
}
}
return hasError;
}

判断有验证错误 就不执行提交。


/// <summary>
/// 获取DataGrid的第一个被发现的验证错误结果。
/// </summary>
/// <param name="dg">被检查的DataGrid实例。</param>
/// <returns>错误结果。</returns>
public static ValidationError GetDataGridRowsFirstError(DataGrid dg)
{
ValidationError err=null;
for (int i = 0; i < dg.Items.Count; i++)
{
DependencyObject o = dg.ItemContainerGenerator.ContainerFromIndex(i);
bool hasError = Validation.GetHasError(o);
if (hasError)
{
err = Validation.GetErrors(o)[0];
break;
}
}
return err;
}

/// <summary>
/// 执行检查DataGrid,并提示第一个错误。重新定位到错误单元格。
/// </summary>
/// <param name="dg">被检查的DataGrid实例。</param>
/// <returns>true 有错并定位,false 无错、返回</returns>
public static bool ExcutedCheckedDataGridValidation(DataGrid dg)
{
ValidationError err = GetDataGridRowsFirstError(dg);
if (err != null)
{
string errColName = ((System.Windows.Data.BindingExpression)err.BindingInError).ParentBinding.Path.Path;
DataGridColumn errCol = dg.Columns.Single(p =>
{
if (((Binding)((DataGridTextColumn)p).Binding).Path.Path == errColName)
return true;
else return false;
});
//string errRow = ((DataRowView)((System.Windows.Data.BindingExpression)err.BindingInError).DataItem)["SWH"].ToString();
//dg.Items.IndexOf(((System.Windows.Data.BindingExpression)err.BindingInError).DataItem);
dg.SelectedItem = ((System.Windows.Data.BindingExpression)err.BindingInError).DataItem;
int errRowIndex = dg.SelectedIndex;
MessageBox.Show(string.Format("第\"{0}\"行 的\"{1}\"列的单元格数据不合法(以红色标出),请填写正确后再执行其他操作。", errRowIndex + 1, errCol.Header), "系统消息", MessageBoxButton.OK, MessageBoxImage.Warning);

dg.CurrentCell = new DataGridCellInfo(dg.SelectedItem, errCol);
if (!((DataRowView)dg.CurrentItem).IsEdit)
{
((DataRowView)dg.CurrentItem).BeginEdit();

}
TextBox txt = dg.CurrentColumn.GetCellContent(dg.CurrentItem) as TextBox;
txt.Focus();
return true;
}
else
{
return false;
}
}


这个用来重新定位到错误单元格
  • 打赏
  • 举报
回复
粗暴的香蕉 2011-05-21
怎么没人回答啊…………
  • 打赏
  • 举报
回复
粗暴的香蕉 2011-05-21
没有人能提供一下解决方法吗?
  • 打赏
  • 举报
回复
粗暴的香蕉 2011-05-21
补充一下吧
DataGrid里面我用了样式触发器
如下:

<DataGrid AutoGenerateColumns="False" Height="279" HorizontalAlignment="Left" Margin="6,6,0,0" Name="dgItv" VerticalAlignment="Top" Width="353" CellEditEnding="dgItv_CellEditEnding">
<DataGrid.Resources>
<Style x:Key="cellErrorStyle" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Red"></Setter>
<Setter Property="ToolTip" Value="请输入整数!"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="区间表示" Binding="{Binding line_id}" Visibility="Hidden"></DataGridTextColumn>
<DataGridTextColumn Header="线路名" Binding="{Binding line_name}" Width="Auto" CanUserResize="False" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Header="区间名" Binding="{Binding itv_name}" Width="*" CanUserResize="False" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Header="区间通过时间" Binding="{Binding itv_time, ValidatesOnExceptions=True}" EditingElementStyle="{StaticResource cellErrorStyle}"
Width="Auto" CanUserResize="False"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>


我想在cellErrorStyle这个样式被ValidatesOnExceptions=True触发时,可以通知一个button设置它的IsEnalbed为false,通过验证后,设回true
  • 打赏
  • 举报
回复
发帖
C#
加入

10.7w+

社区成员

.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
申请成为版主
帖子事件
创建了帖子
2011-05-21 06:28
社区公告

让您成为最强悍的C#开发者