WPF: Detect row validation errors in C# code

后端 未结 3 716
借酒劲吻你
借酒劲吻你 2021-01-06 07:29

I want to achieve a pretty simple task, but none of the solutions here on SO or otherwise found have helped me so far:

I have a WPF DataGrid, which is b

相关标签:
3条回答
  • Why dont you catch the attached bubbling routed event Validation.Error on your data grid?

      <DataGrid x:Name="mydataGrid" Validation.Error="MyValidationErrorHandler" ... />
    

    Make sure you have NotifyOnValidationError=true in your bindings. This way you would know that error has been raised and show that in your messagebox.

    But do you really "know" there are errors on the datagrid? I mean do you see the errors highlighted using red border , tooltips, row validation error template etc? Isnt that sufficient to indicate to user?

    Cant you use

      Validation.GetHasError(mydataGrid)
    

    to check if its in error?

    0 讨论(0)
  • 2021-01-06 08:13

    This seems a near duplicate of this [question]: (Checking If Any WPF DataGrid Cell Has Error).

    Here's an answer that's more XAMly. It relies on the fact that when an error template is shown its IsVisible property toggles.

    Just create a ValidationErrorTemplate for the DataGridRow [1]: (http://msdn.microsoft.com/en-us/library/ee622975.aspx)

    Create 2 attacheded properties. The value of the one attached property is the DataGrid itself,

    local:DataGridValidator.DataGridToMarkForValidationErrors="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}}"
    

    Attach the property to the root control of the ValidationErrorTemplate.

    In the callback for the attached property set the 2nd property on the DataGrid to show whether it has errors:

            private static void DataGridPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            var fe = dependencyObject as FrameworkElement;
            var target = args.NewValue as DependencyObject;
    
            if (fe != null && target != null)
            {
                target.SetValue(IsFreeOfValidatoionErrorsProperty, !fe.IsVisible);
    
                fe.IsVisibleChanged += (_1, _) =>
                {
                    target.SetValue(IsFreeOfValidatoionErrorsProperty, !fe.IsVisible);
                };
    
            }
    

    Now the DataGrid has a property (IsFreeOfValidatoionErrorsProperty) showing whether it has errors or not. I made the property default positive so I could easily AND it with my VM IsDirty/CanSave property.

    0 讨论(0)
  • 2021-01-06 08:25

    OK, I've worked it out. The following does what I want:

    public static DataGridRow GetRow(DataGrid grid, int index)
    {
        DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
        if (row == null)
        {
            // May be virtualized, bring into view and try again.
            grid.UpdateLayout();
            grid.ScrollIntoView(grid.Items[index]);
            row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
        }
        return row;
    }
    

    In the code for my "OK" button I do:

    for (int i = 0; i < dgvData.Items.Count; i++)
    {
        DataGridRow row = GetRow(dgvData, i);
        if (row != null && Validation.GetHasError(row))
        {
            hasDataGridErrors = true;
            break;
        }
    }
    
    0 讨论(0)
提交回复
热议问题