Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force DataGrid column validation (WPF)

I would like to know how to programmatically fire validation over a DataGridColumn. It would be pretty much the same as it is donde calling the UpdateSource method of a BindingExpression, but I cant manage to get the BindingExpression of the column.

Thanks.

PS: setting the ValidatesOnTargetUpdated property on the ValidationRule is not what I'm looking for :)

like image 420
juanedi Avatar asked Nov 04 '10 17:11

juanedi


People also ask

How do I use validation in DataGrid?

The DataGrid control enables you to perform validation at both the cell and row level. With cell-level validation, you validate individual properties of a bound data object when a user updates a value. With row-level validation, you validate entire data objects when a user commits changes to a row.

How to validate data in WPF DataGrid (sfdatagrid)?

WPF DataGrid (SfDataGrid) allows you to validate the data and display hints in case of validation is not passed. In case of invalid data, error icon is displayed at the top right corner of GridCell. When mouse over the error icon, error information will be displayed in tooltip.

How do I check if data is valid in WPF DataGrid?

Data Validation in WPF DataGrid (SfDataGrid) SfDataGrid allows you to validate the data and display hints in case of validation is not passed. In case of invalid data, error icon is displayed at the top right corner of GridCell. When mouse over the error icon, error information will be displayed in tooltip.

How does cellvalidating work in datagridview?

When the user edits a cell in the CompanyName column, its value is tested for validity by checking that it is not empty. If the event handler for the CellValidating event finds that the value is an empty string, the DataGridView prevents the user from exiting the cell until a non-empty string is entered.


2 Answers

In the .NET Framework 4, a namespace called System.ComponentModel.DataAnnotations is available for both the common CLR (WPF) and the lighter Silverlight CLR. You can use the DataAnnotations namespace for various purposes. One of these is for data validation using attributes, and another is the visual description of fields, properties, and methods, or to customize the data type of a specific property. These three categories are classified in the .NET Framework as Validation Attributes, Display Attributes, and Data Modeling Attributes. This section uses Validation Attributes to define validation rules for objects

http://www.codeproject.com/KB/dotnet/ValidationDotnetFramework.aspx

like image 78
Irfan Shaikh Avatar answered Nov 09 '22 05:11

Irfan Shaikh


@user424096,

I have no access to my visual studio environment, but following pseudo code may guide you for your desired way...

  1. Create an attached boolean property called NotifySourceUpdates and attach is to DataGridCell... I have attached it at datagrid level so that it applies to all data grid cells... you can attach it at column level as well...

            <DataGrid ItemsSource="{Binding}">
                    <DataGrid.CellStyle>
                            <Style TargetType="DataGridCell" >
                                    <Setter Property="ns:MyAttachedBehavior.NotifySourceUpdates" Value="True"/>
                            </Style>
                    </DataGrid.CellStyle>
            </DataGrid>
    
  2. This attached behavior will handle the attached event called Binding.SourceUpdated at the cell level. So whenever any binding as part of any child UI element's normal or edit mode has its source updated, it will fire and bubble to the cell level.

            public static readonly DependencyProperty NotifySourceUpdatesProperty
            = DependencyProperty.RegisterAttached(
              "NotifySourceUpdates",
              typeof(bool),
              typeof(MyAttachedBehavior),
              new FrameworkPropertyMetadata(false, OnNotifySourceUpdates)
            );
    
            public static void SetNotifySourceUpdates(UIElement element, bool value)
            {
                element.SetValue(NotifySourceUpdatesProperty, value);
            }
    
            public static Boolean GetNotifySourceUpdates(UIElement element)
            {
                return (bool)element.GetValue(NotifySourceUpdatesProperty);
            }
    
            private static void OnNotifySourceUpdates(DependencyObject d, DependencyPropertyEventArgs e)
            {
                if ((bool)e.NewValue)
                {
                    ((DataGridCell)d).AddHandler(Binding.SourceUpdated, OnSourceUpdatedHandler);
                }
            }
    
  3. In this event handler, the event args are of type DataTransferEventArgs which gives you the TargetObject. This will be your control that needs to validate.

    private static void OnSourceUpdatedHandler(object obj, DataTransferEventArgs e) //// Please double check this signature
    {
        var uiElement = e.TargetObject as UIElement;
        if (uiElement != null)
        {
            ///... your code to validated uiElement.                        
        }
    }
    
  4. Here you must know what value represented by the control is valid or invalid.

    (uiElement.MyValue == null) //// Invalid!!
    
  5. If you want the control's binding to invalidate, just use the MarkInvalid call using these steps...

    ValidationError validationError = 
            new ValidationError(myValidationRule, 
            uiElement.GetBindingExpression(UIElement.MyValueDependecyProperty));
    
    validationError.ErrorContent = "Value is empty!";
    
    Validation.MarkInvalid(uiElement.GetBindingExpression(UIElement.MyValueDependencyProperty), validationError);
    

Let me know if this works...

like image 44
WPF-it Avatar answered Nov 09 '22 07:11

WPF-it