验证telerik GridView每行中的每个控件(ValidationRule)。 WPF

时间:2012-12-19 09:16:55

标签: c# wpf validation gridview datatemplate

我有一个包含9列的RadGridView。每一列都包含文本框,除了第二和第九:第二个是组合框,第九个是drag'n'rop的图像。我需要验证我的GridView,如果行中的任何列为空,我不能单击保存按钮。

每个单元格都被定义为数据模板:

        <t:RadGridView.Resources>
            <DataTemplate x:Key="DraggedItemTemplate">
                <StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{x:Static p:Resources.AddStandardWindow_TextBlock_Dragging}" />
                        <TextBlock Text="{Binding CurrentDraggedItem.SpecificationName}" FontWeight="Bold" />
                    </StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding CurrentDropPosition}" FontWeight="Bold" MinWidth="45" Foreground="Gray"/>
                        <TextBlock Text=", (" Foreground="Gray" />
                        <TextBlock Text="{Binding CurrentDraggedOverItem.SpecificationName}" Foreground="Gray" />
                        <TextBlock Text=")" Foreground="Gray" />
                    </StackPanel>
                </StackPanel>
            </DataTemplate>
        </t:RadGridView.Resources>

        <t:RadGridView.Columns>
            <t:GridViewColumn>
                <t:GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <t:RadButton Content="X" Click="OnDeleteSpecificationButtonClicked" Style="{StaticResource ButtonCustomStyleRed}" />
                    </DataTemplate>
                </t:GridViewColumn.CellTemplate>
            </t:GridViewColumn>

            <t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Specifications}">
                <t:GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Style="{StaticResource OverrideDefaultTextBoxStyle}" TextChanged="OnRowTextBoxesTextChanged" Text="{Binding SpecificationName}"/>
                    </DataTemplate>
                </t:GridViewColumn.CellTemplate>
            </t:GridViewColumn>

            <t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Parameter}" Width="20*">
                <t:GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <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">
                            <t:RadComboBox.SelectedItem>
                                <Binding Path="Parameter" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
                                    <Binding.ValidationRules>
                                        <validation:ProductVariantValidation ValidatesOnTargetUpdated="True" />
                                    </Binding.ValidationRules>
                                </Binding>
                            </t:RadComboBox.SelectedItem>
                        </t:RadComboBox>
                    </DataTemplate>
                </t:GridViewColumn.CellTemplate>
            </t:GridViewColumn>

            <t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Nominal}" Width="20*">
                <t:GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Style="{StaticResource OverrideDefaultTextBoxStyle}" TextChanged="OnRowTextBoxesTextChanged" KeyDown="OnKeyDown" Text="{Binding Nominal, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" SourceUpdated="OnNominalOrAccuracySourceUpdated">
                        </TextBox>
                    </DataTemplate>
                </t:GridViewColumn.CellTemplate>
            </t:GridViewColumn>

            <t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Accuracy}" 
                              Width="10*" Background="#D8E5F0">
                <t:GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Style="{StaticResource OverrideDefaultTextBoxStyle}" KeyDown="OnKeyDown" Text="{Binding Accuracy,
                            NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" TextChanged="OnRowTextBoxesTextChanged" SourceUpdated="OnNominalOrAccuracySourceUpdated" />
                    </DataTemplate>
                </t:GridViewColumn.CellTemplate>
            </t:GridViewColumn>


            <t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Precision}"
                                  Width="10*"
                                  Background="#D8E5F0">
                <t:GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox KeyDown="OnKeyDown" Text="{Binding Presition, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" 
                                 TextChanged="OnRowTextBoxesTextChanged" Style="{StaticResource OverrideDefaultTextBoxStyle}">
                        </TextBox>
                    </DataTemplate>
                </t:GridViewColumn.CellTemplate>
            </t:GridViewColumn>

            <t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Min}" Width="10*">
                <t:GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Style="{StaticResource OverrideDefaultTextBoxStyle}" 
                                 TextChanged="OnRowTextBoxesTextChanged" KeyDown="OnKeyDown" Text="{Binding Minimum, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" SourceUpdated="OnMinOrMaxSourceUpdated">
                        </TextBox>
                    </DataTemplate>
                </t:GridViewColumn.CellTemplate>
            </t:GridViewColumn>
            <t:GridViewColumn Header="{x:Static p:Resources.AddStandardWindow_Max}" Width="10*">
                <t:GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Style="{StaticResource OverrideDefaultTextBoxStyle}" TextChanged="OnRowTextBoxesTextChanged" KeyDown="OnKeyDown" 
                                 Text="{Binding Maximum, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" SourceUpdated="OnMinOrMaxSourceUpdated">
                        </TextBox>
                    </DataTemplate>
                </t:GridViewColumn.CellTemplate>
            </t:GridViewColumn>
            <t:GridViewColumn Width="40">
                <t:GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Image Source="/Images/UpDown.png" Height="34" Width="34" Stretch="None"/>
                    </DataTemplate>
                </t:GridViewColumn.CellTemplate>
            </t:GridViewColumn>
        </t:RadGridView.Columns>
    </t:RadGridView>

我尝试为其中一个控件应用验证规则,这样如果验证有错误,则会禁用保存按钮。这是按钮的样式:

<t:RadButton x:Name="SaveBtn" Height="30" Width="150" Content="{x:Static p:Resources.AddStandardWindow_Btn_Save}" Command="{Binding SaveStandardCommand}">
                <t:RadButton.Style>
                    <Style TargetType="{x:Type t:RadButton}" BasedOn="{StaticResource ButtonCustomStyleBlue}">
                        <Setter Property="IsEnabled" Value="false" />
                        <Style.Triggers>
                            <!-- Require the controls to be valid in order to press OK -->
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding ElementName=StandardTitleTextBox, Path=(Validation.HasError)}" Value="false"/>
                                    <Condition Binding="{Binding ElementName=StandardSubtitleTextBox, Path=(Validation.HasError)}" Value="false"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="IsEnabled" Value="true" />
                            </MultiDataTrigger>
                        </Style.Triggers>
                    </Style>
                </t:RadButton.Style>
            </t:RadButton>

这里,StandardTitle和StandardSubtitle不在GridView中,但是如果我在GridView单元格模板中添加元素名称添加新条件,则ValidationRule不起作用,因为它看不到该控件。

目前,我正在尝试在背后的代码中实现我的目标:

protected void OnKeyDown(object sender,KeyEventArgs e)         {             e.Handled =!IsNumberKey(e.Key)&amp;&amp; !IsActionKey(e.Key);         }

    private bool IsNumberKey(Key inKey)
    {
        if (inKey < Key.D0 || inKey > Key.D9)
        {
            if (inKey == Key.OemPeriod) return true;
            if (inKey < Key.NumPad0 || inKey > 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<GridViewRow>().ParentOfType<RadGridView>();

        ValidateGridView(gridView);
    }

    void ValidateGridView(RadGridView gridView)
    {
        var textboxes = gridView.ChildrenOfType<TextBox>();
        var comboboxes = gridView.ChildrenOfType<RadComboBox>();

        if (null != textboxes && null != comboboxes)
            SaveBtn.IsEnabled = textboxes.All(p => p.Text.Length != 0) && comboboxes.All(p => null != p.SelectedItem);
    }

    private void OnParameterBoxChanged(object sender, SelectionChangedEventArgs e)
    {
        var combobox = sender as RadComboBox;
        if (null == combobox) return;

        var row = combobox.ParentOfType<GridViewRow>();
        var boxes = row.ChildrenOfType<TextBox>();

        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<RadWindow>().FindChildByType<RadGridView>();
        gridView.RowLoaded += OnGridViewRowLoaded;
    }

    void OnGridViewRowLoaded(object sender, RowLoadedEventArgs e)
    {
        var a = e.Row.ParentOfType<RadGridView>();
        ValidateGridView(a);
    }

但是当我添加新行时,仍然会启用该按钮,还有许多其他错误。

我的问题是否有正常的解决方法?谢谢!

0 个答案:

没有答案