This is a migrated thread and some comments may be shown as answers.

ItemsControl in RadDataForm: dynamic data form fields and validation

5 Answers 323 Views
DataForm
This is a migrated thread and some comments may be shown as answers.
Johannes
Top achievements
Rank 1
Johannes asked on 06 Feb 2015, 10:12 AM
I have to create some dynamic data fields inside RadDataForm so I've added an ItemsControl inside my RadDataForm. Please see code below for example. Everything works fine. A custom DataTemplateSelector checks a property called Value. If Value is of type string ItemsControl is using DataFormDataField template to display it with a TextBox. If Value is of type datetime ItemsControl is using DataFormDateField template to display it with a RadDatePicker. That's great but I'm having trouble with validation. I use Item level attribute-based validation as described in your documentation. This works perfect on usual data fields like the two shown below (ID and Name). But validation is not executed on my bound properties inside those mentioned DataTemplates. Inside every DataTemplate there is a DataBinding to property Value of my ViewModel. Just like ID and Name, Value also has Item level attribute-based validation ([Required(AllowEmptyStrings = false)]). When ID or Name are empty validation comes into place and I can not commit RadDataForm until I enter some text. That's what I want for my Value property, too. I hope this is understandable.


<!-- ID -->
<t:DataFormDataField Label="ID" Description="Todo" DataMemberBinding="{Binding ID, Mode=OneWay}">
    <t:DataFormDataField.Content>
        <t:RadWatermarkTextBox Text="{Binding ID, Mode=OneWay}" IsReadOnly="True" />
    </t:DataFormDataField.Content>
</t:DataFormDataField>
<!-- Name -->
<t:DataFormDataField Label="Name" Description="Todo" DataMemberBinding="{Binding Name, Mode=TwoWay, NotifyOnValidationError=True}">
    <t:DataFormDataField.Content>
        <t:RadWatermarkTextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" WatermarkContent="Please fill in your name" />
    </t:DataFormDataField.Content>
</t:DataFormDataField>
<!-- DYNAMIC DATA FIELDS -->
<ItemsControl ItemsSource="{Binding Source={StaticResource CollectionViewSource}}" Focusable="False">
    <ItemsControl.ItemTemplateSelector>
        <v:MyDataTemplateSelector>
            <!-- Text DataTemplate (Value is string so show it in DataFormDataField) -->
            <v:MyDataTemplateSelector.TextBoxDataTemplate>
                <DataTemplate>
                    <t:DataFormDataField Label="{Binding Label, Mode=OneWay}" Description="{Binding ToolTip, Mode=OneWay}" DataMemberBinding="{Binding Value, Mode=TwoWay, NotifyOnValidationError=True}">
                        <t:DataFormDataField.Content>
                            <t:RadWatermarkTextBox Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" WatermarkContent="Please insert value" />
                        </t:DataFormDataField.Content>
                    </t:DataFormDataField>
                </DataTemplate>
            </v:MyDataTemplateSelector.TextBoxDataTemplate>
            <!-- Date DataTemplate (Value is datetime so show it as DataFormDateField) -->
            <v:MyDataTemplateSelector.DateDataTemplate>
                <DataTemplate>
                    <t:DataFormDateField Label="{Binding Label, Mode=OneWay}" Description="{Binding ToolTip, Mode=OneWay}" DataMemberBinding="{Binding Value, Mode=TwoWay, NotifyOnValidationError=True}">
                        <t:DataFormDateField.Content>
                            <t:RadDatePicker DateSelectionMode="Year" SelectedValue="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                        </t:DataFormDateField.Content>
                    </t:DataFormDateField>
                </DataTemplate>
            </v:MyDataTemplateSelector.DateDataTemplate>
            <!-- More DataTemplates here ... -->
        </v:MyDataTemplateSelector>
    </ItemsControl.ItemTemplateSelector>
</ItemsControl>


Can you help me on this? I don't know what I am doing wrong here. It seems my validation rules/data annotations are just not recognized by RadDataForm when the binding is inside a DataTemplate.

5 Answers, 1 is accepted

Sort by
0
Johannes
Top achievements
Rank 1
answered on 06 Feb 2015, 10:18 AM
I want to add that property Value is of type object so it can be string, int or else. That's why I have to use different DataTemplates/Controls to make Value editable via my UI. The code shown above is located inside my RadDataForms EditTemplate.
0
Ivan Ivanov
Telerik team
answered on 11 Feb 2015, 09:42 AM
Hi,

Please excuse me for the late reply. Generally, we rely on Validatior.ValidateObject to retrieve the validation errors of the current item. Here is the actual snippet of our source code:
Validator.TryValidateObject(this.CurrentItem, new ValidationContext(this.CurrentItem, null, null), validationResults, true);
Thus validation relies exclusively on the value of the properties, and not on editor bindings. Can you please confirm whether Value, Name and ID are members of one and the same type and Value is not a nested property to the type of DataForm's CurrentItem?

Regards,
Ivan Ivanov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Johannes
Top achievements
Rank 1
answered on 11 Feb 2015, 10:47 AM
Thanks for your reply. ID and Name are in the same ViewModel, for example ProductViewModel. ProductViewModel then would have this fields: ID (int), Name (string) and DataFields (ObservableCollection<DataFieldViewModel>). DataFieldViewModel then has properties Label, ToolTip and Value. So Value is not in the same ViewModel as ID and Name, it's in a nested ViewModel.

As shown above I have an ItemsControl inside my RadDataForm that is bound to that ObservableCollection. I assumed that validation is automatically executed on every bound/visible value but you wrote that's not the case. So if I understand you correctly only RadDataForm's CurrentItem is validated. Is there some way to override/extend this? I have to validate the properties of my nested ViewModels, too.
0
Johannes
Top achievements
Rank 1
answered on 11 Feb 2015, 02:59 PM
Ok I've managed to extend validation for my needs. Please take a look at this:

bool result = base.OnValidateItem(); // calls RadDataForm.ValidateItem
 
if (DataForm != null)
{
    var product = DataForm.CurrentItem as IProductDataItemViewModel;
 
    if (product != null)
    {
        var errors = new List<ValidationResult>();
 
        var productValidationResult = Validator.TryValidateObject(product, new ValidationContext(product, null, null), errors, true);
 
        if (productValidationResult == false)
        {
            result = false;
        }
 
        // Check DataFields in ProductViewModel
        foreach (var dataField in product.DataFields)
        {
            var dataFieldValidationResult = Validator.TryValidateObject(dataField, new ValidationContext(dataField, null, null), errors, true);
 
            if (dataFieldValidationResult == false)
            {
                result = false;
            }
        }
 
        if (errors.Any())
        {
            // How to populate Errors to the UI?
        }
    }
}
             
return result;



When I check RadDataForm's ValidationSummary property I can see the errors for nested property Value but how can I populate them to the UI? There is a method



0
Ivan Ivanov
Telerik team
answered on 16 Feb 2015, 10:48 AM
Hello,

You can add your own validation errors to the UI like this:
dataForm.ValidationSummary.Errors.Add(new Telerik.Windows.Controls.Data.ErrorInfo() { ErrorContent = "Name should be no shorter than 2 characters", SourceFieldDisplayName = "Name" });
Please, be advised that these errors should be handled manually and they will not be automatically cleared as soon as he validation condition is met.

Regards,
Ivan Ivanov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
DataForm
Asked by
Johannes
Top achievements
Rank 1
Answers by
Johannes
Top achievements
Rank 1
Ivan Ivanov
Telerik team
Share this question
or