WPF/MVVM validation in listview (items)

Topics: General discussion, Validation Application Block
Jan 2, 2011 at 11:14 PM

Hi

I'm trying to figure out, how to implement entlib 5.0 in a WPF listview.
I have a WPF application with a view and 2 viewmodels.
The view consists of the upper part with 2 textfields with a simply "required" validation. these 2 elements are in the first viewmodel.

The second part of the view is a listview. Every "listview-item" is a set of 1 dropdown and a textbox. these "listview-items" are in a separate viewmodel.

When I apply the validation on the second viewmodel (the one with the lsit of items) the validation works only for the first entry. After I create more then 1 entry, the validation does not work.

I think the entlib validation can't distinguish which elements has been validated and which are not.

An example could be a view with a renter of a car and the history of his rented cars.
You have one view with the details of the renter in the upper part (first viewmodel) and at the bottom of this view you have a listview, which is implemented in a second (separate) viewmodel. The listview-item consists of 1 textbox a 1 dropdown. Both have to be required.

Thank you a lot for your help!

Best regards,
Michele

Jan 2, 2011 at 11:22 PM

Could you explain how you implemented the validation on the listview? 

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Jan 3, 2011 at 1:58 PM

Hi

The view has 3 fields and a style, that describes the "special" listbox
The fields are:

<Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="10"/>
                    <ColumnDefinition Width="0.25*"/>
                    <ColumnDefinition Width="10"/>
                    <ColumnDefinition Width="0.25*"/>
                    <ColumnDefinition Width="10"/>
                    <ColumnDefinition Width="0.25*"/>
                    <ColumnDefinition Width="10"/>
                    <ColumnDefinition Width="0.25*"/>
                    <ColumnDefinition Width="10"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="0"/>
                    <RowDefinition Height="0.19*"/>
                    <RowDefinition Height="5"/>
                    <RowDefinition Height="0.275*"/>
                    <RowDefinition Height="5.87"/>
                    <RowDefinition Height="0.291*"/>
                    <RowDefinition Height="5.636"/>
                    <RowDefinition Height="0.245*"/>
                    <RowDefinition Height="5.333"/>
                </Grid.RowDefinitions>
                <Label x:Name="lblRackDetails" Content="Rack Details" Grid.Column="1" Margin="0" Grid.ColumnSpan="3" Style="{DynamicResource LabelStyle}" Grid.Row="1" FontSize="18.667" FontWeight="Bold"/>
                <Label x:Name="lblMinVal" Content="Minimum" Grid.Column="1" Margin="0" Grid.Row="3" Style="{DynamicResource LabelStyle}"/>
                <Label x:Name="lblMaxVal" Content="Maximum" Grid.Column="1" Margin="0" Grid.Row="5" Style="{DynamicResource LabelStyle}" />
                <Label x:Name="lblComment" Content="Comment" Grid.Column="1" Margin="0" Grid.Row="7" Style="{DynamicResource LabelStyle}" />

                
                
                <TextBox x:Name="minVal" Grid.Column="3" Margin="0" Grid.Row="3" 
                    TextWrapping="NoWrap" 
                    VerticalAlignment="Top" 
                    Padding="2" 
                    Height="{DynamicResource SensitiveHeight}" 
                    MinHeight="{DynamicResource SensitiveHeight}" 
                    MaxHeight="{DynamicResource SensitiveHeight}" 
                    Text="{Binding MinValue, 
                            Mode=TwoWay, 
                            UpdateSourceTrigger=PropertyChanged,  
                            ValidatesOnExceptions=true, 
                            ValidatesOnDataErrors=true, 
                            NotifyOnValidationError=true}" 
                    ctrl:RegexInteractor.RegexEntry="False"
                    ctrl:RegexInteractor.Expression="^[1-9]+[0-9]{0,3}$" 
                    Style="{DynamicResource MandatoryInputTextBoxStyle}"
                    Validation.ErrorTemplate="{StaticResource InvisibleValidationErrorTemplate}"
                        >
                    <TextBox.InputBindings>
                        <KeyBinding Command="ApplicationCommands.NotACommand" Key="V" Modifiers="Control" />
                    </TextBox.InputBindings>
                </TextBox> 
               
                <TextBox x:Name="maxVal" Grid.Column="3" 
                    Margin="0" 
                    Grid.Row="5" 
                    TextWrapping="NoWrap" 
                    Text="{Binding MaxValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" 
                    Height="{DynamicResource SensitiveHeight}" 
                    MinHeight="{DynamicResource SensitiveHeight}" 
                    MaxHeight="{DynamicResource SensitiveHeight}"
                    ctrl:RegexInteractor.RegexEntry="False"
                    ctrl:RegexInteractor.Expression="^[1-9]+[0-9]{0,3}$"
                    Style="{DynamicResource MandatoryInputTextBoxStyle}" 
                    Validation.ErrorTemplate="{StaticResource InvisibleValidationErrorTemplate}"
                        >
                    <TextBox.InputBindings>
                        <KeyBinding Command="ApplicationCommands.NotACommand" Key="V" Modifiers="Control" />
                    </TextBox.InputBindings>
                </TextBox> 
                
                <TextBox x:Name="comment" Grid.ColumnSpan="5" 
                        Grid.Column="3" 
                        Grid.Row="7" 
                        Height="{DynamicResource SensitiveHeight}" 
                        MinHeight="{DynamicResource SensitiveHeight}" 
                        MaxHeight="{DynamicResource SensitiveHeight}"
                        Text="{Binding Comment, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" 
                        VerticalAlignment="Center" 
                        Style="{DynamicResource MandatoryInputTextBoxStyle}" 
                        Validation.ErrorTemplate="{StaticResource InvisibleValidationErrorTemplate}"
                        >
                    <TextBox.InputBindings>
                        <KeyBinding Command="ApplicationCommands.NotACommand" Key="V" Modifiers="Control" />
                    </TextBox.InputBindings>
                </TextBox> 
            </Grid>
The style for the ListBox is following:
 <Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Border Margin="0,5" BorderThickness="0,0,0,1" CornerRadius="0" Style="{DynamicResource BorderStyleInstrumentDefault}" Padding="5" d:DesignWidth="820" MaxWidth="820" MinWidth="820" d:DesignHeight="234.12" Background="{x:Null}" >
                                <Grid Height="Auto" >
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto" MinWidth="99.5" />
                                        <ColumnDefinition Width="143.25"/>
                                        <ColumnDefinition Width="109.25" />
                                        <ColumnDefinition Width="129"/>
                                        <ColumnDefinition Width="0.257*"/>
                                        <ColumnDefinition Width="0.743*"/>
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="42"/>
                                        <RowDefinition Height="109.667"/>
                                        <RowDefinition Height="70.953"/>
                                    </Grid.RowDefinitions>

                                    <Label x:Name="lblTest" Content="Test"  Margin="5,0,0,0" Grid.Column="0" VerticalAlignment="Center" Style="{DynamicResource NormalLabelStyle}" Height="Auto" />
                                    <ComboBox x:Name="TestTypeSelection" Grid.ColumnSpan="1" Grid.Column="1" 
                                        DisplayMemberPath="Name"
                                        SelectedValuePath="Id"
                                        SelectedIndex="-1"
                                        Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}"
                                        SelectedValue="{Binding TestDefinitionId}" 
                                        ItemsSource="{Binding DataContext.TestTypeItemsSource, ElementName=TestDetailsList}" 
                                        />

                                    <Label x:Name="CommentLabel" Content="Comment" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="1" Margin="0" VerticalAlignment="Center" Style="{DynamicResource NormalLabelStyle}" Height="Auto" />
                                    <TextBox x:Name="Comment" Height="Auto"  Grid.Column="1"
                                     Grid.Row="1" Grid.ColumnSpan="6" Margin="0,10" VerticalAlignment="Stretch" 
                                     Text="{Binding Comment, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" 
                                     MaxLength="255" TextWrapping="Wrap" MinLines="1" VerticalScrollBarVisibility="Auto" 
                                     MaxLines="2" Style="{DynamicResource MultiLineTextBoxStyle}" Padding="2" />

                                    <Label x:Name="OrderDateLabel" Content="Order date" Height="Auto" Margin="0" VerticalAlignment="Center" Grid.Row="2" Style="{DynamicResource NormalLabelStyle}" />
                                    <Button Grid.Column="6" Grid.Row="2" x:Name="RemoveButton" Grid.ColumnSpan="1" Content="Delete" Command="{Binding DeleteCommand}" Click="Delete_Click" VerticalAlignment="Center" Height="{DynamicResource SensitiveHeight}" Style="{DynamicResource ButtonDeleteStyle}" />
                                    <TextBlock Grid.Row="2" Text="{Binding CreationDate}" FontSize="16" Grid.ColumnSpan="2" Height="Auto" Grid.Column="1" Margin="0" VerticalAlignment="Center" Foreground="{DynamicResource TextForeground93}" HorizontalAlignment="Left" />
                                </Grid>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
There are 2 viewmodels.  
The min, max and comment field are in one view model and the "tests" (the listbox) are in a other viewmodel.
I have a printscreen. Should I send it via email to you?
thank you for your support.
by
Michele
Jan 3, 2011 at 2:03 PM

I have also notices, that because there are 2 "comment" fields (in two different viewmodels, but in the same view), the validation does not work properly.

How should the validation be implemented for such a list?
Or is the list implemented the wrong way?

Thank you again.

By

Michele

Jan 4, 2011 at 9:22 AM

Hi Michele,

I haven't really tried it yet in a listbox in WPF. Do you have any simple example repro project for this that we can try to have further investigation? Thanks

Gino Terrado
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

 

Jan 5, 2011 at 3:04 AM

Are you dealing with a listbox or listview?  The screenshot you sent shows only one item per listbox (or listview?) so I'm wondering about your first description of the problem wherein only the first item gets validated. 

A small repro of what you're exactly trying to do  would be helpful.

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com