3

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;
    }
  }

}
4

1 に答える 1

5

3つのことを追加して動作させました:

于 2013-06-13T20:48:52.100 に答える