2016-08-19 18 views
1

RowValidationRulesマークアップ内に検証ルールを持つDataGridがあります。DataGridから無効な行を自動的に修正/削除します

私が望むのは、検証エラーがない場合にのみバインドされたプロパティを更新することです。それ以外の場合は古い値を保持する必要があります。

XAML:

<DataGrid       
Margin="10" 
CanUserAddRows="True" 
CanUserDeleteRows="True" 
AutoGenerateColumns="False" 
IsReadOnly="False" 
ItemsSource="{Binding Source={x:Static services:SharedPropertiesProvider.Instance}, Path=Aliases, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"       
> 

<DataGrid.RowValidationRules> 
    <validation:AliasValidation /> 
</DataGrid.RowValidationRules> 
<DataGrid.Columns> 
    <DataGridTextColumn Width="30*" Header="Alias" Binding="{Binding Key, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn> 
    <DataGridTextColumn Width="70*" Header="Path" Binding="{Binding Value, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn> 
    <DataGridTemplateColumn> 
     <DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <Button Command="ApplicationCommands.Delete" Width="20" Height="20"> 
        <Button.Content> 
         <Image Margin="2" Source="/WinLogInspector;component/Assets/1441392968_f-cross_256.png" /> 
        </Button.Content> 
       </Button> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellTemplate> 
    </DataGridTemplateColumn> 
</DataGrid.Columns> 

バリデーションクラス:

class AliasValidation : ValidationRule { 
public override ValidationResult Validate(object value, CultureInfo cultureInfo) { 
    if (((BindingGroup)value).Items.Count > 0) 
    { 
     Alias item = (value as BindingGroup).Items[0] as Alias; 

     if (item != null) 
     { 
      string aliasPattern = @"^[a-zA-Z]+[a-zA-Z0-9]*$"; 

      string pathPattern = @"^[a-zA-Z0-9\\/@:_\-;]+$"; 

      string key = item.Key ?? String.Empty; 

      string path = item.Value ?? String.Empty; 

      bool isValidAlias = Regex.IsMatch(key, aliasPattern); 

      bool isValidPath = Regex.IsMatch(path, pathPattern); 

      if (isValidAlias && isValidPath) 
       return ValidationResult.ValidResult; 
      else 
       return new ValidationResult(false, "Invalid alias/path"); 
     } 
    }    

    return ValidationResult.ValidResult; 

} } 

のviewmodelでプロパティ:

public ObservableCollection<Alias> Aliases { get; set; } 

class Alias 
{ 
    public string Key { get; set; } 

    public string Value { get; set; } 

} 

だからのviewmodelから任意のコマンドを実行しようとした場合私はエイリアスプロパティの行が無効です。 これをどのように消毒することができますか?

+0

Alias ViewModel/ModelでIDataErrorInfoを使用することをおすすめします。私の使用から、検証に失敗した場合、バインディングは更新されません。しかし、私はこの方法が驚いています。実際のItemsControlでバリデーションを行っていますか? – Joe

+0

あなたは、問題はバインディングの代わりにデータグリッドにバリデーションを入れているということですか? –

+0

私はそう思って、私の考えを答えに入れてください。 – Joe

答えて

1

まあ、私は完全に間違っていました。検証に失敗するとバインディングが更新されます。私は、現時点では考えることができる唯一の回避策は、新たな表示プロパティを持っている、ともセッターに検証することです...

public string key; 
    public string Key { 
     get { return key; } 
     set 
     { 
      if (key != value && this["KeyDisplay"] == string.Empty) 
      { 
       key = value; 
       NotifyPropertyChanged("Key"); 
      } 
     } 
    } 

    public string _value; 
    public string Value 
    { 
     get { return _value; } 
     set 
     { 
      if (_value != value && this["ValueDisplay"] == string.Empty) 
      { 
       _value = value; 
       NotifyPropertyChanged("Value"); 
      } 
     } 
    } 

    public string keyDisplay; 
    public string KeyDisplay 
    { 
     get { return keyDisplay; } 
     set 
     { 
      if (keyDisplay != value) 
      { 
       keyDisplay = value; 
       Key = value; 
       NotifyPropertyChanged("KeyDisplay"); 
      } 
     } 
    } 

    public string valueDisplay; 
    public string ValueDisplay 
    { 
     get { return valueDisplay; } 
     set 
     { 
      if (valueDisplay != value) 
      { 
       valueDisplay = value; 
       Value = value; 
       NotifyPropertyChanged("ValueDisplay"); 
      } 
     } 
    } 

    public string this[string columnName] 
    { 
     get 
     { 
      if (columnName == nameof(KeyDisplay) || columnName == nameof(ValueDisplay)) 
      { 
       string aliasPattern = @"^[a-zA-Z]+[a-zA-Z0-9]*$"; 

       string pathPattern = @"^[a-zA-Z0-9\\/@:_\-;]+$"; 

       string key = KeyDisplay ?? String.Empty; 

       string path = ValueDisplay ?? String.Empty; 

       bool isValidAlias = Regex.IsMatch(key, aliasPattern); 

       bool isValidPath = Regex.IsMatch(path, pathPattern); 

       if (isValidAlias && isValidPath) 
        return string.Empty; 
       else 
        return "Invalid alias/path"; 
      } 
      return string.Empty; 
     } 
    } 

これは、元の答えと完全に間違っています!妥当性検査では、バインディングに関連付けられたプロパティの更新ができません。私はそれらのプロパティが実際に検証されていないため、プロパティが検証をパスしなくても設定されていると思います。 NotifyOnValidationError=Trueの検証は、ItemsControl ItemsSourceプロパティでのみ有効です。

MVVMでは、IDataErrorInfoを使用し、ViewModelまたはモデルで検証することをお勧めします。検証は関連する表示ではなく、私の意見ではビューには含まれません。

class Alias : IDataErrorInfo 
{ 
    public string Key { get; set; } 

    public string Value { get; set; } 

    public string this[string columnName] 
    { 
     get 
     { 
      if (columnName == nameof(Key) || columnName == nameof(Value)) 
      { 
       string aliasPattern = @"^[a-zA-Z]+[a-zA-Z0-9]*$"; 

       string pathPattern = @"^[a-zA-Z0-9\\/@:_\-;]+$"; 

       string key = Key ?? String.Empty; 

       string path = Value ?? String.Empty; 

       bool isValidAlias = Regex.IsMatch(key, aliasPattern); 

       bool isValidPath = Regex.IsMatch(path, pathPattern); 

       if (isValidAlias && isValidPath) 
        return string.Empty; 
       else 
        return "Invalid alias/path"; 
      } 
      return string.Empty; 
     } 
    } 

    public string Error 
    { 
     get 
     { 
      return string.Empty; 
     } 
    } 
} 

また、バインディングロジックでデータモデル全体に​​アクセスできるので、複数のプロパティが有効であることを確認する際の柔軟性が向上します。 ValidationRulesでは、マルチバインディングや何かを混乱させなければならないかもしれないと思います。

キーバインドと値バインディングで検証を使用した場合は、ValidationRulesを使用します。Binding="{Binding Key, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True...}">これらは失敗した場合に更新されるべきではありません。

+0

私はコードを更新しました(ValidatesOnDataErrors = Trueも追加する必要がありましたが、無効なデータがまだ取られています):( –

+0

検証エラーが出ていますか? – Joe

+0

はい!エラーメッセージ –

関連する問題