中の技術日誌ブログ

C#とC++/CLIと
VBと.NETとWindowsで戯れる
 

目次

Blog 利用状況

ニュース

自己紹介

東京でソフトウェアエンジニアをやっています。
お仕事大募集中です。
記事執筆や、講師依頼とかでも何でもどうぞ(*^_^*)
似顔絵 MSMVPロゴ
MSMVP Visual C# Since 2004/04-2013/03

記事カテゴリ

書庫

日記カテゴリ

00-整理

01-MSMVP

XAMLでのエラー通知

通常XAMLアプリケーションを作成し、バインディングを利用しているとエラー通知にルールというものを使います。

ちなみにネット上にはまだ情報がないと思うので、最新のMSDNライブラリか日本語版のWindowsSDKを落として

データ バインディングの概要
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.ja/wpf_conceptual/html/c707c95f-7811-401d-956e-2fffd019a211.htm

を見てみてください。下のほうです。

でこのエラー通知にToolTipを使う簡単な方法というのが書かれています。

<Style x:Key="textStyleTextBox" TargetType="TextBox">
  <Setter Property="Foreground" Value="#333333" />
  <Setter Property="MaxLength" Value="40" />
  <Setter Property="Width" Value="392" />
  <Style.Triggers>
    <Trigger Property="Validation.HasError" Value="true">
      <Setter Property="ToolTip"
        Value="{Binding RelativeSource={RelativeSource Self},
                        Path=(Validation.Errors)[0].ErrorContent}"/>
    </Trigger>
  </Style.Triggers>
</Style>

この[0]が直書きされているパターンのTipsは結構どこにでも転がっています。

ただこれをそのまま利用してみると非常に問題が多いです。

ミニマムセットを作って実験してみると、入力エラーなどを発生させると以下のようなスタックトレースが出力にはかれます。

System.Windows.Data Error: 12 : Cannot get '' value (type 'ValidationError') from '(Validation.Errors)' (type 'ReadOnlyObservableCollection`1'). BindingExpression:Path=(0).[0].ErrorContent; DataItem='TextBox' (Name='textBox1'); target element is 'TextBox' (Name='textBox1'); target property is 'ToolTip' (type 'Object') TargetInvocationException:'System.Reflection.TargetInvocationException: 呼び出しのターゲットが例外をスローしました。 ---> System.ArgumentOutOfRangeException: インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
パラメータ名: index
   場所 System.ThrowHelper.ThrowArgumentOutOfRangeException()
   場所 System.Collections.Generic.List`1.get_Item(Int32 index)
   場所 System.Collections.ObjectModel.Collection`1.get_Item(Int32 index)
   場所 System.Collections.ObjectModel.ReadOnlyCollection`1.get_Item(Int32 index)
   --- 内部例外スタック トレースの終わり ---
   場所 System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
   場所 System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
   場所 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   場所 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   場所 MS.Internal.Data.PropertyPathWorker.GetValue(Object item, Int32 level)
   場所 MS.Internal.Data.PropertyPathWorker.RawValue(Int32 k)'

かんぜんにエラーのパターンから[0]としているけど、1件もないエラーが発生しています。

ドキュメント上はこれをするようにと書かれているにもかかわらずこんな状態ということからバグじゃないかと思います。

エラーが発生するとValidation.Errorsにエラーがたまって、Validation.HasErrorにフラグがたつと書かれているのですが、逆にしてしまっているのじゃないかと思います。

さて解決策。

このToolTipに出力しているのがただのバインド式ということなので、コンバータで解決します。

public class ErrorContentConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        
        ReadOnlyObservableCollection<ValidationError>  col = value as ReadOnlyObservableCollection<ValidationError>;
        if (col == null)
        {
            return "";
        }
        else
        {
            if (col.Count > 0)
            {
                return col[0].ErrorContent;
            }
            else
            {
                return "";
            }
        }
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new Exception("The method or operation is not implemented.");
    }
}

かようなコンバータを作成します。

<Trigger Property="Validation.HasError" Value="true">
  <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},Path=(Validation.Errors), Converter={StaticResource ErrorContentConverter}}"/>
</Trigger>

一部リソース式などは省略しているので、そこはうまくやってください。

ということで、こうすれば当然の如くうまくいきますので、 みなさん対処してくださいね。

投稿日時 : 2007年7月1日 22:42

コメントを追加

# bague avec diamant cartier replica 2017/12/23 18:51 decsjxajwffzefslxdtbxr@hotmal.com

Bien remarqué dans "Judas" de Lady Gaga, j'augure un super acteur ; bonne gueule, bon jeu, j'ai hâte de le voir dans un 1er rôle à sa mesure.
bague avec diamant cartier replica http://www.bijouxpascher.net/category/bague-love-cartier-replique

タイトル
名前
URL
コメント