12

WPF エラー テンプレートを WPF の UserControl 内のコントロールに表示するにはどうすればよいですか?

2 つのラベル、2 つの TextBoxes、および CheckBox を含む UserControl があります。TextBoxes の 1 つはエンティティの名前を表し、ViewModel によって公開される Model プロパティの Name プロパティにバインドされます。これは、私の Window の DataContext です。Model クラスは IDataErrorInfo インターフェイスを実装しており、単体テストを通じて、Name が空白の場合、プロパティ インデクサーの実装によってエラーが返されることを確認しました。UserControl の Name TextBox をサポートする Dependency Property にバインドしました。検証エラーが発生すると、WPF エラー テンプレートは、Name TextBox だけでなく、UserControl 全体に赤い境界線を配置します。

UserControl の name フィールドへのバインドは次のとおりです。

<vc:MyUserControl ItemName="{Binding Model.Name, ValidatesOnDataErrors=True}" />

私の UserControl とバッキング DependencyProperty の単純化されたバージョンは次のとおりです。

<UserControl>
    <Grid>
       <TextBox Text="{Binding ItemName}" />
    </Grid>
</UserControl>

public partial class MyUserControl: UserControl
{
    public static readonly DependencyProperty ItemNameProperty = 
        DependencyProperty.Register(
            "ItemName", 
            typeof(string), 
            typeof(MyUserControl), 
            new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
    );

    public string ItemName
    {
        get { return (string)GetValue(ItemNameProperty); }
        set { SetValue(ItemNameProperty, value); }
    }
}

これまでにこの問題に関連して見つけた情報はすべて、Silverlight に関するものか、コンバーターを使用して赤い境界線を表示しないことに関するものでした (これは私には意味がありませんでした)。この情報はすべて、stackoverflow で見つかりました。

WPFでこの問題を解決できた人はいますか? 私は明らかな何かを見落としていますか?

4

1 に答える 1

12

ErrorTemplateforは、UserControl使用にバインドする場合に使用されUserControlますValidatesOnDataErrors=Trueただし、 Validation.ErrorTemplateAttachedプロパティを使用して赤い境界線を削除できます。

内のすべてのコントロールは、バッキングDependencyPropertiesにもUserControl実装してバインディングを検証した場合にのみ、赤い境界線を表示します。IDataErrorInfo

public class MyUserControl : UserControl, IDataErrorInfo
{
   public static readonly DependencyProperty ItemNameProperty =
       DependencyProperty.Register(
           "ItemName",
           typeof(string),
           typeof(MyUserControl),
           new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
   );

   public string ItemName
   {
      get { return (string)GetValue(ItemNameProperty); }
      set { SetValue(ItemNameProperty, value); }
   }

   public string Error
   {
      get { throw new NotImplementedException(); }
   }

   public string this[string columnName]
   {
      get
      {
         // use a specific validation or ask for UserControl Validation Error 
         return Validation.GetHasError(this) ? "UserControl has Error" : null;
      }
   }
}

そしてここで簡略化されたXAML

<UserControl Validation.ErrorTemplate="{x:Null}">
   <Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
      <TextBox Text="{Binding ItemName, ValidatesOnDataErrors=True}" />
   </Grid>
</UserControl>

添加

エラーを区別したい場合は、DependencyPropertyのBindingExpressionを取得して、HasErrorプロパティを確認できます。

BindingExpression be = BindingOperations.GetBindingExpression(this, ItemNameProperty);
return be != null && be.HasError ? "ItemName has Error" : null;
于 2013-02-20T13:08:57.257 に答える