禁用基于DataGrid DataGridTextColumn验证失败的按钮

时间:2013-06-12 19:44:11

标签: c# wpf validation xaml datagrid

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

使用ValidationRule执行DataGrid验证。

我在StackOverflow上阅读了几篇密切相关的文章,但我仍然被卡住了。我认为问题是验证是在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;
    }
  }

}

1 个答案:

答案 0 :(得分:5)

我通过添加3件事来实现它: