装飾の概要
装飾は、ユーザーにビジュアル キューを提供するために使用する、特別な種類の FrameworkElement です。 装飾にはさまざまな使用法があり、要素に機能ハンドルを追加したり、コントロールに関する状態情報を提供するためなどに使用できます。
このトピックは、次のセクションで構成されています。
- 装飾について
- カスタム装飾を実装する
- 装飾のレンダリング動作
- イベントおよびヒット テスト
- 単一の UIElement を装飾する
- パネルの子を装飾する
- 関連トピック
装飾について
Adorner は、UIElement にバインドされるカスタム FrameworkElement です。 装飾は、AdornerLayer に描画されます。これは、常に装飾対象の要素またはそのコレクションの上に存在するレンダリング サーフェイスです。 装飾の描画は、その装飾がバインドされる UIElement の描画とは独立して実行されます。 通常、装飾は、装飾対象の要素の左上に位置する標準の 2-D 座標の原点を使用して、バインド先の要素に対して相対的な位置に配置されます。
装飾の一般的な用途には、以下が含まれます。
ユーザーが要素を何らかの方法で操作 (サイズ変更、回転、位置変更など) できるようにする機能ハンドルを UIElement に追加する。
さまざまな状態を示すために、または各種のイベントへの対応として、視覚的フィードバックを提供する。
UIElement に視覚的装飾をオーバーレイする。
UIElement の一部または全部を視覚的にマスクまたはオーバーライドする。
Windows Presentation Foundation (WPF) は、ビジュアル要素を装飾するための基本的なフレームワークを提供します。 オブジェクトを装飾する際に使用する主なクラスと、その用途の一覧を次の表に示します。 その後に、いくつかの使用方法の例を示します。
すべての具体的な装飾の実装の継承元になる抽象基本クラス。 |
|
装飾される 1 つ以上の要素について、装飾のレンダリング層を表すクラス。 |
|
1 つの装飾層を要素のコレクションに関連付けることを可能にするクラス。 |
カスタム装飾を実装する
Windows Presentation Foundation (WPF) が提供する装飾フレームワークは、カスタム装飾の作成をサポートすることを主な目的としています。 抽象型 Adorner クラスから継承されるクラスを実装することにより、カスタムの Adorner が作成されます。
メモ |
---|
Adorner の親は、装飾される要素ではなく、Adorner を描画する AdornerLayer です。 |
簡単な装飾を実装するクラスを次の例に示します。 この例の装飾は、UIElement の四隅を円で装飾します。
Public Class SimpleCircleAdorner
Inherits Adorner
Sub New(ByVal adornedElement As UIElement)
MyBase.New(adornedElement)
End Sub
Protected Overrides Sub OnRender(ByVal drawingContext As System.Windows.Media.DrawingContext)
MyBase.OnRender(drawingContext)
Dim adornedElementRect As New Rect(AdornedElement.DesiredSize)
Dim renderBrush As New SolidColorBrush(Colors.Green)
renderBrush.Opacity = 0.2
Dim renderPen As New Pen(New SolidColorBrush(Colors.Navy), 1.5)
Dim renderRadius As Double
renderRadius = 5.0
'Draw a circle at each corner.
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, renderRadius, renderRadius)
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, renderRadius, renderRadius)
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, renderRadius, renderRadius)
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, renderRadius, renderRadius)
End Sub
End Class
// Adorners must subclass the abstract base class Adorner.
public class SimpleCircleAdorner : Adorner
{
// Be sure to call the base class constructor.
public SimpleCircleAdorner(UIElement adornedElement)
: base(adornedElement)
{
}
// A common way to implement an adorner's rendering behavior is to override the OnRender
// method, which is called by the layout system as part of a rendering pass.
protected override void OnRender(DrawingContext drawingContext)
{
Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
// Some arbitrary drawing implements.
SolidColorBrush renderBrush = new SolidColorBrush(Colors.Green);
renderBrush.Opacity = 0.2;
Pen renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);
double renderRadius = 5.0;
// Draw a circle at each corner.
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, renderRadius, renderRadius);
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, renderRadius, renderRadius);
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, renderRadius, renderRadius);
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, renderRadius, renderRadius);
}
}
TextBox に適用された SimpleCircleAdorner を次の図に示します。
装飾のレンダリング動作
Adorner 自体には継承されたレンダリング動作は含まれず、Adorner のレンダリングは Adorner の実装者の責任で行う必要がある点について注意が必要です。 レンダリング動作を実装する一般的な方法としては、OnRender メソッドをオーバーライドし、1 つ以上の DrawingContext オブジェクトを使用して、装飾のビジュアルを必要に応じて描画します (上の例を参照)。
メモ |
---|
装飾層に配置されているすべてのものは、設定した他のすべてのスタイルの上に描画されます。つまり、装飾は常に視覚的に最上位にあり、z オーダーを使用してオーバーライドすることはできません。 |
イベントおよびヒット テスト
他のすべての FrameworkElement と同様に、装飾も入力イベントを受け取ります。 装飾は、それが装飾する要素よりも常に高い z オーダーを持つため、下位にある装飾対象の要素に向けられた入力イベント (たとえば Drop や MouseMove) であっても受け取ります。 装飾は、特定の入力イベントをリッスンし、それらのイベントを再び発生させることによって下位にある装飾対象の要素に渡すことができます。
装飾を通過させてその下にある要素のヒット テストを有効にするには、その装飾でヒット テストの IsHitTestVisible プロパティを false に設定します。 ヒット テストの詳細については、次を参照してください。
単一の UIElement を装飾する
Adorner を特定の UIElement にバインドするには、次の手順を実行します。
静的メソッド GetAdornerLayer を呼び出し、修飾対象の UIElement の AdornerLayer オブジェクトを取得します。 GetAdornerLayer は、指定した UIElement を起点にしてビジュアル ツリーを上方向に検索し、最初に見つかった修飾層を返します。 (Adorner のレイヤーが見つからない場合は、メソッドにより null が返されます。)
次の例では、SimpleCircleAdorner (前述) を TextBox (名前は myTextBox) にバインドしています。
myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox)
myAdornerLayer.Add(New SimpleCircleAdorner(myTextBox))
myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox);
myAdornerLayer.Add(new SimpleCircleAdorner(myTextBox));
メモ |
---|
Adorner を別の要素にバインドするために Extensible Application Markup Language (XAML) を使用することは、現在サポートされていません。 |
パネルの子を装飾する
Adorner を Panel の子にバインドするには、次の手順を実行します。
静的メソッド GetAdornerLayer を呼び出し、子が装飾の対象となる要素の装飾層を検出します。
親要素の子を列挙し、Add メソッドを呼び出して Adorner を各子要素にバインドします。
次の例では、SimpleCircleAdorner (前述) を StackPanel の子 (名前は myStackPanel) にバインドしています。
For Each toAdorn As UIElement In myStackPanel.Children
myAdornerLayer.Add(New SimpleCircleAdorner(toAdorn))
Next
foreach (UIElement toAdorn in myStackPanel.Children)
myAdornerLayer.Add(new SimpleCircleAdorner(toAdorn));