2017-09-11 23 views
1

2つの列を持つ単純な標準WPF 4 DataGridがあります。WPF:すべてのDataGridTemplateColumnsで検証エラーが表示されるDataGrid

<DataGrid ItemsSource="{Binding Source={StaticResource ItemDataView}}" AutoGenerateColumns="False"> 
    <DataGrid.Columns> 
     <DataGridTemplateColumn Header="Alpha"> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Alpha}" /> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
     <DataGridTemplateColumn Header="Beta"> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Beta}" /> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 

表示されたデータオブジェクトはように定義される:

public class MyObject : INotifyDataErrorInfo 
{ 
    [Required] 
    public string Alpha { get; set; } 

    public string Beta { get; set; } 

    public bool HasErrors 
    { 
     get { return string.IsNullOrEmpty(Alpha); } 
    } 

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; 

    public IEnumerable GetErrors(string propertyName) 
    { 
     yield return propertyName; 
    } 
} 

すなわちアルファ空でない値を有していなければならないが、ベータはnullにすることができます。

アルファ値が空の場合はとなります。アルファとベータのセルには、検証エラーを示す赤い枠が付けられています。これはDataGridTemplateColumnsでのみ発生します。 DataGridTextColumnを追加しようとしましたが、赤い枠線が得られません。ベータ列は、何かに束縛されていない場合、またはコントロールが接続されていない場合でも(たとえば、DataTemplateが空の場合)、赤い枠線を取得します。

a)これはなぜ発生しますか?

b)どうやって止めることができますか?私はエラーのセル上に赤いバリデーションの境界線が必要です。

+0

あなたのHasErrors関数は、アルファの評価のみを返します。だから、ベータ細胞はアルファ細胞の状態が何であれミラーリングするだけです。 –

答えて

1

INotifyDataErrorInfoがエラーの有無を判断するために使用されます。具体的には、エラーが存在するかどうかを示すためにtrueまたはfalseを返すようにHasErrorsプロパティを実装する必要があります。あなたのケースでは、HasErrors実装は唯一Alphaを見ている:

public bool HasErrors 
{ 
    get { return string.IsNullOrEmpty(Alpha); } 
} 

だから、Alphaがnullまたは空の場合、エラーがあることのみが表示されます。

あなたはこのように、両方をチェックすることを変更する必要があります:

public bool HasErrors 
{ 
    get 
    { 
     return !AlphaIsValid || !BetaIsValid; 
    } 
} 

private bool AlphaIsValid 
{ 
    get {return !string.IsNullOrEmpty(Alpha);} 
} 

private bool BetaIsValid 
{ 
    get {return Beta == null || Beta != "";} 
} 

その後、GetErrors()で、それはAlphaまたはBetaと一致するかどうかを確認し、エラーメッセージを提供することで渡された文字列をチェックします

public IEnumerable GetErrors(string propertyName) 
{ 
    if (propertyName == nameof(Alpha) && !AlphaIsValid) 
    { 
     return new []{"Alpha is null or empty"}; 
    } 
    if (propertyName == nameof(Beta) && !BetaIsValid) 
    { 
     return new []{"Beta is empty"}; 
    } 
    return Enumerable.Empty<string>(); 
} 

プロパティのエラーがない場合は、空のコレクションを返します。

現在、両方のプロパティの値を返しています(プロパティ名を返すだけであるため)、両方とも検証エラーがあるとマークされています。

参考:https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifydataerrorinfo(v=vs.110).aspx

+1

ベータ版のチェックを変更してヌルを許可してください。これは非常に良い答えです。 –

+0

@PaulGibsonありがとうございます。私はその部分を見落とした。回答が更新されました。 –

+0

私は問題をあまり単純化していました。あなたの参照リンクを読んで、私は実際のコードの問題点を知りました。パラメータがnullの場合、すべての検証エラーを返すGetErrorsの実装を使用していました。この参照は、エンティティレベルエラーのみがその場合に返されるべきであることを示す。 GetErrorsは、バインディングの有無に関係なく、DataGridTemplateColumnのnullパラメータで呼び出されるようです。 – Deadlock320

関連する問題