装飾の概要
装飾は特殊な種類の FrameworkElementであり、ユーザーに視覚的な手掛かりを提供するために使用されます。 他の用途と同様に、アドーナーは要素に機能するハンドルを追加したり、コントロールの状態情報を提供したりするために使用できます。
装飾について
Adorner は、UIElementにバインドされたカスタム FrameworkElement です。 装飾は、AdornerLayerでレンダリングされます。これは、装飾された要素または装飾された要素のコレクションの上に常に存在するレンダリング サーフェイスです。 装飾のレンダリングは、装飾がバインドされる UIElement のレンダリングとは独立しています。 装飾は通常、装飾要素の左上にある標準の 2D 座標原点を使用して、それがバインドされる要素を基準にして配置されます。
装飾の一般的なアプリケーションは次のとおりです。
- ユーザーが何らかの方法で要素を操作できる機能ハンドルを UIElement に追加する (サイズ変更、回転、再配置など)。
- さまざまな状態を示したり、さまざまなイベントに応答したりするための視覚的なフィードバックを提供します。
- UIElementに視覚的な装飾を重ね合わせ。
- UIElementの一部またはすべてを視覚的にマスクまたはオーバーライドします。
Windows Presentation Foundation (WPF) には、ビジュアル要素を装飾するための基本的なフレームワークが用意されています。 次の表に、オブジェクトを装飾するときに使用される主な型とその目的を示します。 いくつかの使用例を次に示します。
クラス | 説明 |
---|---|
Adorner | すべての具象装飾実装が継承する抽象基本クラス。 |
AdornerLayer | 装飾される 1 つ以上の要素に対する、装飾のレンダリング層を表すクラス。 |
AdornerDecorator | 装飾レイヤーを要素のコレクションに関連付けるクラス。 |
カスタム装飾の実装
Windows Presentation Foundation (WPF) によって提供される装飾フレームワークは、主にカスタム装飾の作成をサポートすることを目的としています。 カスタム装飾は、抽象 Adorner クラスから継承するクラスを実装することによって作成されます。
手記
Adorner の親は、装飾される要素ではなく、Adorner をレンダリングする AdornerLayer です。
次の例は、単純な装飾を実装するクラスを示しています。 この例の装飾は、単に UIElement の角を円で飾ります。
// 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);
}
}
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
次の図は、TextBoxに適用された SimpleCircleAdorner を示しています。
装飾のレンダリング動作
装飾には固有のレンダリング動作は含まれていないことに注意することが重要です。装飾がレンダリングされることを保証することは、装飾実装者の責任です。 レンダリング動作を実装する一般的な方法は、OnRender メソッドをオーバーライドし、1 つ以上の DrawingContext オブジェクトを使用して、必要に応じて装飾のビジュアルをレンダリングすることです (上の例を参照)。
手記
装飾レイヤーに配置されたものはすべて、設定した残りのスタイルの上にレンダリングされます。 言い換えると、装飾要素は常に視覚的に最前面に配置されており、Zオーダーを使用して上書きできません。
イベントとヒット テスト
他のすべての FrameworkElement と同様に、装飾は入力イベントを受け取ります。 装飾は常に装飾する要素よりも z オーダーが高いため、装飾は基になる装飾要素を対象とする入力イベント (Drop や MouseMoveなど) を受け取ります。 装飾は、特定の入力イベントをリッスンし、それらのイベントを再度発生させることによって、下位にある装飾対象の要素に渡すことができます。
アドーナーに対して、ヒット テスト IsHitTestVisible プロパティを false に設定して、アドーナーの下にある要素のパススルーヒットテストを有効にします。 ヒット テストの詳細については、「ビジュアル レイヤーの
単一の UIElement の装飾
装飾を特定の UIElementにバインドするには、次の手順に従います。
静的メソッド GetAdornerLayer を呼び出して、装飾する UIElement の AdornerLayer オブジェクトを取得します。 GetAdornerLayer 指定した UIElementから始まるビジュアル ツリーをウォークアップし、見つけた最初の装飾レイヤーを返します。 (装飾レイヤーが見つからない場合、メソッドは null を返します)。
次の例では、上記の SimpleCircleAdorner を TextBox という名前の myTextBoxにバインドします。
myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox);
myAdornerLayer.Add(new SimpleCircleAdorner(myTextBox));
myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox)
myAdornerLayer.Add(New SimpleCircleAdorner(myTextBox))
手記
拡張アプリケーション マークアップ言語 (XAML) を使用して装飾を別の要素にバインドすることは現在サポートされていません。
パネルの子の装飾
Panel の子に装飾をバインドするには、次の手順を行います。
static
メソッド GetAdornerLayer を呼び出し、子が装飾対象となる要素の装飾層を検出します。親要素の子要素を列挙し、Add メソッドを呼び出してアドーナーを各子要素にバインドします。
次の例では、SimpleCircleAdorner (上図参照) を myStackPanel という名前の StackPanel の子にバインドします。
foreach (UIElement toAdorn in myStackPanel.Children)
myAdornerLayer.Add(new SimpleCircleAdorner(toAdorn));
For Each toAdorn As UIElement In myStackPanel.Children
myAdornerLayer.Add(New SimpleCircleAdorner(toAdorn))
Next
関連項目
.NET Desktop feedback