System.Windows.Controls.DataGrid (WPF、.NET 4.0、C#) を使用しています。セルの検証が失敗した場合 (HasErrors == TRUE)、[OK] ボタンは灰色になります (IsEnabled = FALSE)。
DataGrid の検証は、ValidationRule を使用して実行されます。
ここ StackOverflow で密接に関連する記事をいくつか読んだことがありますが、まだ行き詰っています。問題は、検証が DataGridRow にあることですが、[OK] ボタンの IsEnabled バインディングがグリッド全体を見ていることだと思います。
エラーを確認するには、グリッドに 3 行目を追加し、無効な数値 (例: 200) を入力します。または、2 つの在庫値の 1 つを編集して無効 (0 未満、整数以外、または 100 より大きい) にします。 )。
xaml は次のとおりです。
<Window x:Class="SimpleDataGridValidation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:SimpleDataGridValidation"
Title="MainWindow"
Height="350"
Width="525">
<Window.Resources>
<c:BoolToOppositeBoolConverter x:Key="boolToOppositeBoolConverter" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<DataGrid Name="myDataGrid"
ItemsSource="{Binding}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Time"
x:Name="TimeField">
<DataGridTextColumn.Binding>
<Binding Path="Time"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<c:TimeValidationRule />
</Binding.ValidationRules>
</Binding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
</DataGrid.Columns>
<DataGrid.RowValidationErrorTemplate>
<ControlTemplate>
<Grid Margin="0,-2,0,-2"
ToolTip="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}},
Path=(Validation.Errors)[0].ErrorContent}">
<Ellipse StrokeThickness="0"
Fill="Red"
Width="{TemplateBinding FontSize}"
Height="{TemplateBinding FontSize}" />
<TextBlock Text="!"
FontSize="{TemplateBinding FontSize}"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</DataGrid.RowValidationErrorTemplate>
</DataGrid>
<Button Name="btnOk"
Width="40"
Content="_OK"
IsDefault="True"
Grid.Row="1"
Click="btnOk_Click"
IsEnabled="{Binding ElementName=myDataGrid, Path=(Validation.HasError), Converter={StaticResource boolToOppositeBoolConverter}}">
</Button>
</Grid>
</Window>
C# コード ビハインドは次のとおりです。
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace SimpleDataGridValidation
{
public partial class MainWindow : Window
{
public ObservableCollection<CTransition> Transitions;
public MainWindow()
{
InitializeComponent();
Transitions = new ObservableCollection<CTransition>();
Transitions.Add(new CTransition(10, 5));
Transitions.Add(new CTransition(20, 7));
myDataGrid.DataContext = Transitions;
}
private void btnOk_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
public class CTransition
{
public int Time { get; set; }
public int Speed { get; set; }
public CTransition()
{ }
public CTransition(int thetime, int thespeed)
{
Time = thetime;
Speed = thespeed;
}
}
public class TimeValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value != null)
{
int proposedValue;
if (!int.TryParse(value.ToString(), out proposedValue))
{
return new ValidationResult(false, "'" + value.ToString() + "' is not a whole number.");
}
if (proposedValue > 100)
{
return new ValidationResult(false, "Maximum time is 100 seconds.");
}
if (proposedValue < 0)
{
return new ValidationResult(false, "Time must be a positive integer.");
}
}
// Everything OK.
return new ValidationResult(true, null);
}
}
[ValueConversion(typeof(Boolean), typeof(Boolean))]
public class BoolToOppositeBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (targetType != typeof(bool) && targetType != typeof(System.Nullable<bool>))
{
throw new InvalidOperationException("The target must be a boolean");
}
if (null == value)
{
return null;
}
return !(bool)value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (targetType != typeof(bool) && targetType != typeof(System.Nullable<bool>))
{
throw new InvalidOperationException("The target must be a boolean");
}
if (null == value)
{
return null;
}
return !(bool)value;
}
}
}