Ktouth Brand. on Web

け〜くんこと K.Ktouth のだらだらした日常と突発的に作るプログラムや読み物とかの雑多サイト



[2012年03月21日]

考えすぎてました(ぉ

2012年03月21日 22:35更新 筆者:K.Ktouth

昨日のお悩みの続き。

<kw:BoolToVisibilityConverter x:Key="VisibleOrHidden" TrueValue="Visible" FalseValue="Hidden" />
<Style x:Key="ColumnContent" TargetType="ContentControl">
  <Setter Property="Margin" Value="0,0,20,0" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ContentControl">
        <Grid>
          <Grid Margin="0,0,-20,0"
             Visibility="{Binding (Validation.ValidationAdornerSiteFor).(Validation.HasError), RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource VisibleOrHidden}}"
             ToolTip="{Binding (Validation.ValidationAdornerSiteFor).(Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}">
            <Grid Background="BlanchedAlmond" Opacity="0.5" />
            <Image Width="18" Height="18" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,1,0"
                Source="/FooFoo;component/Resources/warning.png" />
          </Grid>
          <ContentPresenter />
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
  <Setter Property="Validation.ErrorTemplate">
    <Setter.Value>
      <ControlTemplate>
        <Border BorderBrush="Red" BorderThickness="0,0,0,2" CornerRadius="0">
          <Grid>
            <Grid Background="Pink" Opacity="0.25" IsHitTestVisible="False" />
            <AdornedElementPlaceholder Margin="0,0,20,0" />
          </Grid>
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

結局はシンプルにこんな形になりました。
最初の BoolToVisibilityConverter クラスは IValueConverter インターフェイスで文字通り bool 値から Visibility 列挙値に変換するコンバータです。実装は省略。
で、このコンバータを使って、基本テンプレートの ContentPresenter の後ろに検証エラー発生時の背景をあらかじめ設置、先ほどのコンバータを使って表示・非表示を切り替えるようにしました。結局、これは ContentControl を直接使っているので値の編集=実際に検証を行うのは他のコントロールなんですな。つまり何も考えずに Validation.ValidationAdornerSiteFor で取得できるコントロールの値を持ってくるだけで良かったんです。ええ。コンバータを使って値を変換しているので内部のスタイルやらトリガーを使わずにすみ、結果として x:Name 属性が不要になるおまけ付き。
ちなみに Validation.ErrorTemplate はあくまでもエラーテンプレートであり、検証エラーを発生させたコントロールのクラスに紐づけされたものではない(実装的にはそのコントロールを基準に上面にレイアウトされる)ので注意が必要のようでした。

まだこれでもコンテンツ(編集用のコントロール)の上部でツールチップが表示されないという問題があるんですが、むしろもうそれはあると邪魔かも知れないと言うことで無視します!(ぉぃ

本日のリンク元
その他のリンク元
検索