Note that there are some explanatory texts on larger screens.

plurals
  1. POValidate telerik GridView every control in every row (ValidationRule). WPF
    text
    copied!<p>I have a RadGridView with 9 columns. Every column contains textbox, except 2nd and 9th: there's a combobox in 2nd and image for drag'n'rop in the 9th. I need to validate my GridView in the way that if any column in row is empty, I can't click save button.</p> <p>Every cell is defined as data template:</p> <p></p> <pre><code> &lt;t:RadGridView.Resources&gt; &lt;DataTemplate x:Key="DraggedItemTemplate"&gt; &lt;StackPanel&gt; &lt;StackPanel Orientation="Horizontal"&gt; &lt;TextBlock Text="{x:Static p:Resources.AddStandardWindow_TextBlock_Dragging}" /&gt; &lt;TextBlock Text="{Binding CurrentDraggedItem.SpecificationName}" FontWeight="Bold" /&gt; &lt;/StackPanel&gt; &lt;StackPanel Orientation="Horizontal"&gt; &lt;TextBlock Text="{Binding CurrentDropPosition}" FontWeight="Bold" MinWidth="45" Foreground="Gray"/&gt; &lt;TextBlock Text=", (" Foreground="Gray" /&gt; &lt;TextBlock Text="{Binding CurrentDraggedOverItem.SpecificationName}" Foreground="Gray" /&gt; &lt;TextBlock Text=")" Foreground="Gray" /&gt; &lt;/StackPanel&gt; &lt;/StackPanel&gt; &lt;/DataTemplate&gt; &lt;/t:RadGridView.Resources&gt; &lt;t:RadGridView.Columns&gt; &lt;t:GridViewColumn&gt; &lt;t:GridViewColumn.CellTemplate&gt; &lt;DataTemplate&gt; &lt;t:RadButton Content="X" Click="OnDeleteSpecificationButtonClicked" Style="{StaticResource ButtonCustomStyleRed}" /&gt; &lt;/DataTemplate&gt; &lt;/t:GridViewColumn.CellTemplate&gt; &lt;/t:GridViewColumn&gt; &lt;t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Specifications}"&gt; &lt;t:GridViewColumn.CellTemplate&gt; &lt;DataTemplate&gt; &lt;TextBox Style="{StaticResource OverrideDefaultTextBoxStyle}" TextChanged="OnRowTextBoxesTextChanged" Text="{Binding SpecificationName}"/&gt; &lt;/DataTemplate&gt; &lt;/t:GridViewColumn.CellTemplate&gt; &lt;/t:GridViewColumn&gt; &lt;t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Parameter}" Width="20*"&gt; &lt;t:GridViewColumn.CellTemplate&gt; &lt;DataTemplate&gt; &lt;t:RadComboBox x:Name="ParameterComboBox" Style="{StaticResource ComboBoxStyle}" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type t:RadWindow}}, Path=DataContext.Parameters}" DisplayMemberPath="NameUnitOfMeasure" SelectionChanged="OnParameterBoxChanged"&gt; &lt;t:RadComboBox.SelectedItem&gt; &lt;Binding Path="Parameter" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True"&gt; &lt;Binding.ValidationRules&gt; &lt;validation:ProductVariantValidation ValidatesOnTargetUpdated="True" /&gt; &lt;/Binding.ValidationRules&gt; &lt;/Binding&gt; &lt;/t:RadComboBox.SelectedItem&gt; &lt;/t:RadComboBox&gt; &lt;/DataTemplate&gt; &lt;/t:GridViewColumn.CellTemplate&gt; &lt;/t:GridViewColumn&gt; &lt;t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Nominal}" Width="20*"&gt; &lt;t:GridViewColumn.CellTemplate&gt; &lt;DataTemplate&gt; &lt;TextBox Style="{StaticResource OverrideDefaultTextBoxStyle}" TextChanged="OnRowTextBoxesTextChanged" KeyDown="OnKeyDown" Text="{Binding Nominal, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" SourceUpdated="OnNominalOrAccuracySourceUpdated"&gt; &lt;/TextBox&gt; &lt;/DataTemplate&gt; &lt;/t:GridViewColumn.CellTemplate&gt; &lt;/t:GridViewColumn&gt; &lt;t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Accuracy}" Width="10*" Background="#D8E5F0"&gt; &lt;t:GridViewColumn.CellTemplate&gt; &lt;DataTemplate&gt; &lt;TextBox Style="{StaticResource OverrideDefaultTextBoxStyle}" KeyDown="OnKeyDown" Text="{Binding Accuracy, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" TextChanged="OnRowTextBoxesTextChanged" SourceUpdated="OnNominalOrAccuracySourceUpdated" /&gt; &lt;/DataTemplate&gt; &lt;/t:GridViewColumn.CellTemplate&gt; &lt;/t:GridViewColumn&gt; &lt;t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Precision}" Width="10*" Background="#D8E5F0"&gt; &lt;t:GridViewColumn.CellTemplate&gt; &lt;DataTemplate&gt; &lt;TextBox KeyDown="OnKeyDown" Text="{Binding Presition, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" TextChanged="OnRowTextBoxesTextChanged" Style="{StaticResource OverrideDefaultTextBoxStyle}"&gt; &lt;/TextBox&gt; &lt;/DataTemplate&gt; &lt;/t:GridViewColumn.CellTemplate&gt; &lt;/t:GridViewColumn&gt; &lt;t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Min}" Width="10*"&gt; &lt;t:GridViewColumn.CellTemplate&gt; &lt;DataTemplate&gt; &lt;TextBox Style="{StaticResource OverrideDefaultTextBoxStyle}" TextChanged="OnRowTextBoxesTextChanged" KeyDown="OnKeyDown" Text="{Binding Minimum, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" SourceUpdated="OnMinOrMaxSourceUpdated"&gt; &lt;/TextBox&gt; &lt;/DataTemplate&gt; &lt;/t:GridViewColumn.CellTemplate&gt; &lt;/t:GridViewColumn&gt; &lt;t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Max}" Width="10*"&gt; &lt;t:GridViewColumn.CellTemplate&gt; &lt;DataTemplate&gt; &lt;TextBox Style="{StaticResource OverrideDefaultTextBoxStyle}" TextChanged="OnRowTextBoxesTextChanged" KeyDown="OnKeyDown" Text="{Binding Maximum, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" SourceUpdated="OnMinOrMaxSourceUpdated"&gt; &lt;/TextBox&gt; &lt;/DataTemplate&gt; &lt;/t:GridViewColumn.CellTemplate&gt; &lt;/t:GridViewColumn&gt; &lt;t:GridViewColumn Width="40"&gt; &lt;t:GridViewColumn.CellTemplate&gt; &lt;DataTemplate&gt; &lt;Image Source="/Images/UpDown.png" Height="34" Width="34" Stretch="None"/&gt; &lt;/DataTemplate&gt; &lt;/t:GridViewColumn.CellTemplate&gt; &lt;/t:GridViewColumn&gt; &lt;/t:RadGridView.Columns&gt; &lt;/t:RadGridView&gt; </code></pre> <p>I tried to apply a validation rule for one of the controls so that if validation has errors, a save button is disabled. here is style for button:</p> <pre><code>&lt;t:RadButton x:Name="SaveBtn" Height="30" Width="150" Content="{x:Static p:Resources.AddStandardWindow_Btn_Save}" Command="{Binding SaveStandardCommand}"&gt; &lt;t:RadButton.Style&gt; &lt;Style TargetType="{x:Type t:RadButton}" BasedOn="{StaticResource ButtonCustomStyleBlue}"&gt; &lt;Setter Property="IsEnabled" Value="false" /&gt; &lt;Style.Triggers&gt; &lt;!-- Require the controls to be valid in order to press OK --&gt; &lt;MultiDataTrigger&gt; &lt;MultiDataTrigger.Conditions&gt; &lt;Condition Binding="{Binding ElementName=StandardTitleTextBox, Path=(Validation.HasError)}" Value="false"/&gt; &lt;Condition Binding="{Binding ElementName=StandardSubtitleTextBox, Path=(Validation.HasError)}" Value="false"/&gt; &lt;/MultiDataTrigger.Conditions&gt; &lt;Setter Property="IsEnabled" Value="true" /&gt; &lt;/MultiDataTrigger&gt; &lt;/Style.Triggers&gt; &lt;/Style&gt; &lt;/t:RadButton.Style&gt; &lt;/t:RadButton&gt; </code></pre> <p>Here, StandardTitle and StandardSubtitle are out of GridView but if I add new condition with element name, defined in GridView cell templates, ValidationRule is not working because it doesn't see that control.</p> <p>For now, I am trying to achieve my goals in the code behind:</p> <p>protected void OnKeyDown(object sender, KeyEventArgs e) { e.Handled = !IsNumberKey(e.Key) &amp;&amp; !IsActionKey(e.Key); }</p> <pre><code> private bool IsNumberKey(Key inKey) { if (inKey &lt; Key.D0 || inKey &gt; Key.D9) { if (inKey == Key.OemPeriod) return true; if (inKey &lt; Key.NumPad0 || inKey &gt; Key.NumPad9) { return false; } } return true; } private bool IsActionKey(Key inKey) { return inKey == Key.Delete || inKey == Key.Back || inKey == Key.Tab || inKey == Key.Return || Keyboard.Modifiers.HasFlag(ModifierKeys.Alt); } private void OnRowTextBoxesTextChanged(object sender, TextChangedEventArgs e) { var textbox = sender as TextBox; if (null == textbox) return; var gridView = textbox.ParentOfType&lt;GridViewRow&gt;().ParentOfType&lt;RadGridView&gt;(); ValidateGridView(gridView); } void ValidateGridView(RadGridView gridView) { var textboxes = gridView.ChildrenOfType&lt;TextBox&gt;(); var comboboxes = gridView.ChildrenOfType&lt;RadComboBox&gt;(); if (null != textboxes &amp;&amp; null != comboboxes) SaveBtn.IsEnabled = textboxes.All(p =&gt; p.Text.Length != 0) &amp;&amp; comboboxes.All(p =&gt; null != p.SelectedItem); } private void OnParameterBoxChanged(object sender, SelectionChangedEventArgs e) { var combobox = sender as RadComboBox; if (null == combobox) return; var row = combobox.ParentOfType&lt;GridViewRow&gt;(); var boxes = row.ChildrenOfType&lt;TextBox&gt;(); foreach (var textBox in boxes) SaveBtn.IsEnabled = textBox.Text.Length != 0; } private void OnAddSpecificationClick(object sender, RoutedEventArgs e) { var button = sender as RadButton; if (null == button) return; var gridView = button.ParentOfType&lt;RadWindow&gt;().FindChildByType&lt;RadGridView&gt;(); gridView.RowLoaded += OnGridViewRowLoaded; } void OnGridViewRowLoaded(object sender, RowLoadedEventArgs e) { var a = e.Row.ParentOfType&lt;RadGridView&gt;(); ValidateGridView(a); } </code></pre> <p>But when I add new row, the button is still be enabled and there are many other bugs.</p> <p>Is there any normal work around for my problem? Thank you!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload