我有一个包含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);
}
但是当我添加新行时,仍然会启用该按钮,还有许多其他错误。
我的问题是否有正常的解决方法?谢谢!