3

我正在使用 System.Windows.Controls.DataGrid(WPF、.NET 4.0、C#)。如果单元格的验证失败 (HasErrors == TRUE),确定按钮应该是灰色的 (IsEnabled = FALSE)。

使用 ValidationRule 执行 DataGrid 验证。

我在 StackOverflow 上阅读了几篇密切相关的文章,但我仍然卡住了。我认为问题在于 Validation 在 DataGridRow 上,但 OK 按钮的 IsEnabled 绑定正在查看整个网格。

要查看错误,请在网格中添加第三行,并输入无效数字(例如 200)。或者只需将两个股票值之一编辑为无效(小于 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 回答