Validation error in custom column with multiple controls

7 posts, 0 answers
  1. Terry Foster
    Terry Foster avatar
    60 posts
    Member since:
    Sep 2009

    Posted 06 Jun 2011 Link to this post

    I've created a custom column that derives from GridViewBoundColumnBase that has a TextBlock and a RadComboBox as the cell edit elements.  The TextBlock is bound to a property on my view model which implements the INotifyDataErrorInfo interface.  When the user enters an invalid valid, the TextBlock highlights red with an error tip as expected, but the user can end editing for the cell, keeping the invalid value.  This is in direct contrast to the default behavior of the GridViewDataColumn which does not allow the user to end editing until they fix the error or press the 'Esc' key.  How can I get this same behavior for my custom column?

    Thanks,
    Terry
  2. Terry Foster
    Terry Foster avatar
    60 posts
    Member since:
    Sep 2009

    Posted 08 Jun 2011 Link to this post

    Here's a slightly simplified version of my class:

     

     

     

     

    public sealed class GridViewTimeLengthColumn : GridViewBoundColumnBase

     

     

    {

     

     

     

    public bool TimeUnitEnabled { get; set; }

     

     

     

     

    public override string UniqueName

     

     

    {

     

     

     

    get { return base.UniqueName; }

     

     

     

     

    set

     

     

    {

     

     

     

    base.UniqueName = value;

     

     

    DataMemberBinding.Path =

     

    new PropertyPath(value + "Summary"); // for sort/filter/group

     

     

    }

     

    }

     

     

     

    public GridViewTimeLengthColumn()

     

     

    {

     

    TimeUnitEnabled =

     

    true;

     

     

    }

     

     

     

    public override FrameworkElement CreateCellElement(GridViewCell cell, object dataItem)

     

     

    {

     

     

     

    return new TextBlock().SetOneWayBinding(TextBlock.TextProperty, UniqueName + "Summary");

     

     

    }

     

     

     

    public override FrameworkElement CreateCellEditElement(GridViewCell cell, object dataItem)

     

     

    {

     

     

     

    var grid = new Grid();

     

     

    grid.ColumnDefinitions.Add(

     

    new ColumnDefinition());

     

     

    grid.ColumnDefinitions.Add(

     

    new ColumnDefinition() { Width = GridLength.Auto });

     

     

     

     

    var textBox = new TextBox().SetTwoWayBinding(TextBox.TextProperty, UniqueName);

     

     

    grid.Children.Add(textBox);

     

     

     

    var comboBox = new RadComboBox()

     

     

    .SetOneWayBinding(

     

    RadComboBox.ItemsSourceProperty, UniqueName + "TimeUnitItemsSource")

     

     

    .SetTwoWayBinding(

     

    RadComboBox.SelectedItemProperty, UniqueName + "TimeUnit");

     

     

     

     

    Grid.SetColumn(comboBox, 1);

     

     

    comboBox.IsEnabled = TimeUnitEnabled;

     

    grid.Children.Add(comboBox);

     

     

     

    return grid;

     

     

    }

     

    }

     


    The 'SetOneWayBinding' and 'SetTwoWayBinding' methods are just extension methods that establish the bindings and set validation-related binding properties to 'true', all in one convenient call.  As we're quickly approaching a deadline, any timely help you could provide on this would be greatly appreciated.

    Thanks,
    Terry

  3. DevCraft banner
  4. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 09 Jun 2011 Link to this post

    Hi Terry Foster,

    Generally, you may skip setting the validation-related properties of the binding. As once you set them, the Framework will perform the validation. What you may try to do is to handle the CellValidating event of the grid and perform the logic there.
     

    Kind regards,
    Maya
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  5. Terry Foster
    Terry Foster avatar
    60 posts
    Member since:
    Sep 2009

    Posted 09 Jun 2011 Link to this post

    Hi Maya,

    I don't think I'm understanding.  I definitely don't want to handle the CellValidating event of the grid as I'm dong everything MVVM-style.  That is why I'm setting the NotifyOnValidationError and ValidatesOnExceptions properties of the bindings to true.  I'm not sure why you say I can generally skip setting these, as validation through the binding of my view model's properties would no longer work.

    Ultimately, I just need to know exactly what prevents the cell from ending editing when one of the bindings has a validation error (as managed through the INotifyDataErrorInfo interface implemented by the view model) so I can do the same for this custom column.

    Thanks,
    Terry
  6. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 09 Jun 2011 Link to this post

    Hello Terry Foster,

    Basically, for the time being the way to go is to handle the CellValidated event and perform the validation logic there. If you do not want to write any code in your code-behind, you might try to create a custom attached behavior and define it for the RadGridView.
    On the other hand, we will do consider adding a method allowing the implementation of custom validation logic. However, I cannot specify any time frame for including such a feature.
     

    Regards,
    Maya
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  7. Luis Takada
    Luis Takada avatar
    3 posts
    Member since:
    Jun 2010

    Posted 24 Aug 2011 Link to this post

    Hi Maya, as I was searching for a solution to my problem I came across this issue that is somewhat similar to what I have.
    I have a custom cell created in CreateCellEditElement() that is a grid with a textBox and a comboBox. I added the binding and a converter to it. The controls work fine but when I edit the textBox, it fires CellValidating event and there the new value in e.NewValue member is coming as null instead of the edited value.

    private void _grid_CellValidating(object sender, GridViewCellValidatingEventArgs e)
    {
        List<object> values = e.Row.Item as List<object>;
        if (values != null)
        {
            int index = e.Row.Cells.IndexOf(e.Cell);
     
            ScenarioValue value = values[index] as ScenarioValue;
            if (value != null)
            {
                string errorDescription = "";
                e.IsValid = value.IsValid(e.NewValue as string, out errorDescription);
                e.ErrorMessage = errorDescription;
                e.Handled = true;
            }
            else
            {
                Parameter parameter = values[index] as Parameter;
                if (parameter != null)
                {
                    string errorDescription = "";
                    e.IsValid = parameter.IsValid(e.NewValue as string, out errorDescription);
                    e.ErrorMessage = errorDescription;
                    e.Handled = true;
                }
            }
        }
    }
     
     
    public override FrameworkElement CreateCellEditElement(GridViewCell cell, object dataItem)
    {
        List<object> row = dataItem as List<object>;
     
        if (parameter.ParameterType == ParameterType.Time)
        {
            var grid = new Grid();
            grid.ColumnDefinitions.Add(new ColumnDefinition());
            grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
     
            Binding gridBinding = new Binding(DataMemberBinding.Path.Path);
            gridBinding.Mode = BindingMode.TwoWay;
            gridBinding.NotifyOnValidationError = true;
            gridBinding.ValidatesOnExceptions = true;
            gridBinding.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
            gridBinding.Converter = new TimeAndUnitConverter(TimeAndUnitConverter.DataPortion.Time);
            grid.SetBinding(TextBox.TextProperty, gridBinding);
     
     
            var textBox = new TextBox();
            Binding bindingTextBox = new Binding(DataMemberBinding.Path.Path);
            bindingTextBox.Mode = BindingMode.TwoWay;
            bindingTextBox.NotifyOnValidationError = true;
            bindingTextBox.ValidatesOnExceptions = true;
            bindingTextBox.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
            bindingTextBox.Converter = new TimeAndUnitConverter(TimeAndUnitConverter.DataPortion.Time);
            textBox.SetBinding(TextBox.TextProperty, bindingTextBox);
            textBox.Height = 22;
            grid.Children.Add(textBox);
     
            var comboBox = new RadComboBox();
            comboBox.ItemsSource = Parameter.TimeUnits;
     
            Binding bindingCombo = new Binding(DataMemberBinding.Path.Path);
            bindingCombo.Mode = BindingMode.TwoWay;
            bindingCombo.NotifyOnValidationError = true;
            bindingCombo.ValidatesOnExceptions = true;
            bindingCombo.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
            bindingCombo.Converter = new TimeAndUnitConverter(TimeAndUnitConverter.DataPortion.Unit);
            comboBox.SetBinding(RadComboBox.SelectedItemProperty, bindingCombo);
            Grid.SetColumn(comboBox, 1);
            comboBox.IsEnabled = true;
            grid.Children.Add(comboBox);
     
            return grid;
        }
        else
        {
            return base.CreateCellEditElement(cell, dataItem);
        }
    }
  8. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 29 Aug 2011 Link to this post

    Hi Luis Takada,

    This would be the expected behavior since you predefine the editing element of the cell. What you may try is to override the GetNewValueFromEditor(object editor) method in the column definition and return the value you want. Another possible approach would be to find the TextBox/ RadComboBox from the EditingElement property of the arguments of the CellValidating event and get their values.
     

    Best wishes,
    Maya
    the Telerik team

    Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

Back to Top
DevCraft banner