装飾レイヤー(Adorner Layer)
装飾レイヤーとは
装飾対象であるエレメントやコレクションの前面に存在するレイヤーでAdornerを描画する層である.イメージとしては画面上のエレメントなどの上に透明のアクリル板があって,そのアクリル板に描画することで,画面上のエレメントを装飾するというもの.
サンプル
|
+
|
テキストボックスの入力が数字以外であった場合にエラーを表示する |
XAML
<Window x:Class="WpfSampleApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="500">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Width="200" Height="100" LostKeyboardFocus="OnKeyFocusLost_1"/>
<TextBox Width="200" Height="100" LostKeyboardFocus="OnKeyFocusLost_2" Grid.Row="1"/>
</Grid>
</Window>
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Globalization;
namespace WpfSampleApplication
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
Adorner adorner_1;
private void OnKeyFocusLost_1(object s, RoutedEventArgs e)
{
var sender = s as TextBox;
int output;
// TryParseで失敗する場合にAdornerでエラーメッセージを表示する
if(!int.TryParse(sender.Text, out output) )
{
if(adorner_1 != null)
{
// senderの装飾レイヤを取得し,SampleAdornerを追加
var adornerLayer = AdornerLayer.GetAdornerLayer(sender);
if ( adornerLayer != null )
{
adorner_1 = new SampleAdorner(sender);
adornerLayer.Add(adorner_1);
}
}
}
else if ( adorner_1 != null)
{
((AdornerLayer)(adorner_1.Parent)).Remove(adorner_1);
adorner_1 = null;
}
}
Adorner adorner_2;
private void OnKeyFocusLost_2(object s, RoutedEventArgs e)
{
var sender = s as TextBox;
int output;
if (!int.TryParse(sender.Text, out output))
{
if (adorner_2 == null)
{
var adornerLayer = AdornerLayer.GetAdornerLayer(sender);
if (adornerLayer != null)
{
adorner_2 = new SampleAdorner(sender);
adornerLayer.Add(adorner_2);
}
}
}
else if( adorner_2 != null )
{
((AdornerLayer)(adorner_2.Parent)).Remove(adorner_2);
adorner_2 = null;
}
}
private class SampleAdorner : Adorner
{
public SampleAdorner(UIElement adorned)
: base(adorned)
{ }
protected override void OnRender(DrawingContext drawingContext)
{
var rect = new Rect(this.AdornedElement.DesiredSize);
var text = new FormattedText(
"数字以外は入力できません。",
CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface("メイリオ"),
20,
Brushes.Red);
var point = (Point) ( rect.TopLeft - new Point(0, text.Height) );
drawingContext.DrawText(text, point);
}
}
}
}
|