カスタム添付プロパティCustom attached properties

添付プロパティは、XAML の概念です。An attached property is a XAML concept. 添付プロパティは、通常は依存関係プロパティの特殊な形式として定義されます。Attached properties are typically defined as a specialized form of dependency property. このトピックでは、添付プロパティを依存関係プロパティとして実装する方法と、添付プロパティを XAML で使うために必要なアクセサー変換を定義する方法を説明します。This topic explains how to implement an attached property as a dependency property and how to define the accessor convention that is necessary for your attached property to be usable in XAML.

前提条件Prerequisites

依存関係プロパティを既にある依存関係プロパティのユーザーの観点から理解し、「依存関係プロパティの概要」を読んでいることを前提としています。We assume that you understand dependency properties from the perspective of a consumer of existing dependency properties, and that you have read the Dependency properties overview. 添付プロパティの概要」も読んでいる必要があります。You should also have read Attached properties overview. このトピックの例を参考にするには、XAML について理解し、C++、C#、または Visual Basic を使った基本的な Windows ランタイム アプリを作る方法を理解している必要もあります。To follow the examples in this topic, you should also understand XAML and know how to write a basic Windows Runtime app using C++, C#, or Visual Basic.

添付プロパティのシナリオScenarios for attached properties

定義クラス以外のクラスで利用できるプロパティ設定メカニズムが必要な場合は、添付プロパティを作成できます。You might create an attached property when there is a reason to have a property-setting mechanism available for classes other than the defining class. その最も一般的なシナリオは、レイアウトとサービス サポートです。The most common scenarios for this are layout and services support. 既にあるレイアウト プロパティの例として、Canvas.ZIndexCanvas.Top があります。Examples of existing layout properties are Canvas.ZIndex and Canvas.Top. レイアウトのシナリオでは、レイアウト制御要素の子要素として存在する要素は親要素に対するレイアウト要件を個別に表現でき、それぞれ、親が添付プロパティとして定義するプロパティ値を設定します。In a layout scenario, elements that exist as child elements to layout-controlling elements can express layout requirements to their parent elements individually, each setting a property value that the parent defines as an attached property. Windows ランタイム API のサービス サポートのシナリオの例は、ScrollViewer.IsZoomChainingEnabled など、ScrollViewer の添付プロパティのセットです。An example of the services-support scenario in the Windows Runtime API is set of the attached properties of ScrollViewer, such as ScrollViewer.IsZoomChainingEnabled.

警告

Windows ランタイムの XAML 実装の既存の制限は、カスタム添付プロパティをアニメーション化することはできません。An existing limitation of the Windows Runtime XAML implementation is that you cannot animate your custom attached property.

カスタム添付プロパティの登録Registering a custom attached property

他の種類で使う添付プロパティを厳密に定義する場合、プロパティが登録されているクラスが DependencyObject から派生する必要はありません。If you are defining the attached property strictly for use on other types, the class where the property is registered does not have to derive from DependencyObject. ただし、添付プロパティが依存関係プロパティでもある標準モデルに従う場合は、バッキング プロパティ ストアを使うことができるように、アクセサーのターゲット パラメーターで DependencyObject を使う必要があります。But you do need to have the target parameter for accessors use DependencyObject if you follow the typical model of having your attached property also be a dependency property, so that you can use the backing property store.

依存関係プロパティとして宣言することで、添付プロパティを定義、パブリック 静的 readonly型のプロパティ DependencyPropertyします。Define your attached property as a dependency property by declaring a public static readonly property of type DependencyProperty. このプロパティは、RegisterAttached メソッドの戻り値を使って定義します。You define this property by using the return value of the RegisterAttached method. プロパティ名として指定した添付プロパティの名前が一致する必要があります、 RegisterAttached 名前パラメーターで、文字列の末尾に"Property"を追加します。The property name must match the attached property name you specify as the RegisterAttached name parameter, with the string "Property" added to the end. これは、依存関係プロパティが表すプロパティとの関連で依存関係プロパティの識別子に名前を付ける場合の確立された規則です。This is the established convention for naming the identifiers of dependency properties in relation to the properties that they represent.

カスタム添付プロパティを定義する主要領域は、アクセサーまたはラッパーを定義する方法の点でカスタム依存関係プロパティとは異なります。The main area where defining a custom attached property differs from a custom dependency property is in how you define the accessors or wrappers. カスタム依存関係プロパティ」で説明しているラッパー手法を使う代わりに、静的な GetPropertyName メソッドと SetPropertyName メソッドを添付プロパティのアクセサーとして提供する必要もあります。Instead of the using the wrapper technique described in Custom dependency properties, you must also provide static GetPropertyName and SetPropertyName methods as accessors for the attached property. アクセサーは主に XAML パーサーで使われますが、XAML 以外のシナリオでは他の任意の呼び出し元もこれらを使って値を設定できます。The accessors are used mostly by the XAML parser, although any other caller can also use them to set values in non-XAML scenarios.

重要

アクセサーを正しく定義しない場合は、XAML プロセッサが、添付プロパティにアクセスできない可能性がありますが、使用しようとするすべてのユーザーは、XAML パーサー エラーを取得します。If you don't define the accessors correctly, the XAML processor can't access your attached property and anyone who tries to use it will probably get a XAML parser error. また、設計とコーディング ツールの多くの場合、依存、"*プロパティ"参照アセンブリにカスタム依存関係プロパティを検出したときに識別子の名前付け規則。Also, design and coding tools often rely on the "*Property" conventions for naming identifiers when they encounter a custom dependency property in a referenced assembly.

アクセサーAccessors

GetPropertyName アクセサーのシグネチャは次のようにする必要があります。The signature for the GetPropertyName accessor must be this.

public static valueType GetPropertyName (DependencyObject target)public static valueType GetPropertyName (DependencyObject target)

Microsoft Visual Basic の場合は、次のようになります。For Microsoft Visual Basic, it is this.

Public Shared Function GetPropertyName(ByVal target As DependencyObject) AsvalueType)Public Shared Function GetPropertyName(ByVal target As DependencyObject) AsvalueType)

target オブジェクトは実装でより具体的な型にすることができますが、DependencyObject から派生する必要があります。The target object can be of a more specific type in your implementation, but must derive from DependencyObject. valueType 戻り値も、実装でより具体的な型にすることができます。The valueType return value can also be of a more specific type in your implementation. 基本的な Object 型が受け入れられますが、多くの場合、添付プロパティにタイプ セーフを適用します。The basic Object type is acceptable, but often you'll want your attached property to enforce type safety. タイプ セーフ手法として、getter シグネチャと setter シグネチャで型指定を使うことをお勧めします。The use of typing in the getter and setter signatures is a recommended type-safety technique.

シグネチャは、*設定 * * * PropertyNameアクセサーはこれを指定する必要があります。The signature for the *Set***PropertyName accessor must be this.

public static void SetPropertyName(DependencyObject target ,valueTypevalue)public static void SetPropertyName(DependencyObject target ,valueTypevalue)

Visual Basic の場合は、次のようになります。For Visual Basic, it is this.

Public Shared Sub SetPropertyName(ByVal target As DependencyObject, ByVal value AsvalueType)Public Shared Sub SetPropertyName(ByVal target As DependencyObject, ByVal value AsvalueType)

target オブジェクトは実装でより具体的な型にすることができますが、DependencyObject から派生する必要があります。The target object can be of a more specific type in your implementation, but must derive from DependencyObject. value オブジェクトとその valueType は、実装でより具体的な型にすることができます。The value object and its valueType can be of a more specific type in your implementation. 添付プロパティがマークアップに検出された場合、このメソッドの値は XAML プロセッサからの入力であることに注意してください。Remember that the value for this method is the input that comes from the XAML processor when it encounters your attached property in markup. 属性値 (最終的には単なる文字列) から適切な型を作成できるように、使う型の型変換または既存のマークアップ拡張サポートが必要です。There must be type conversion or existing markup extension support for the type you use, so that the appropriate type can be created from an attribute value (which is ultimately just a string). 基本的な Object 型が受け入れられますが、多くの場合、さらにタイプ セーフにします。The basic Object type is acceptable, but often you'll want further type safety. これを実現するには、アクセサーに型を適用します。To accomplish that, put type enforcement in the accessors.

注意

プロパティ要素構文での使用を目的が添付プロパティを定義することもできます。It's also possible to define an attached property where the intended usage is through property element syntax. その場合、値の型変換は必要ではありませんが、意図した値を XAML で確実に作成できるようにする必要があります。In that case you don't need type conversion for the values, but you do need to assure that the values you intend can be constructed in XAML. VisualStateManager.VisualStateGroups のみプロパティ要素による使用をサポートする既存の添付プロパティの例を示します。VisualStateManager.VisualStateGroups is an example of an existing attached property that only supports property element usage.

コードの例Code example

この例は、(RegisterAttached メソッドを使った) 依存関係プロパティの登録と、カスタム添付プロパティの Get アクセサーと Set アクセサーを示しています。This example shows the dependency property registration (using the RegisterAttached method), as well as the Get and Set accessors, for a custom attached property. この例では、添付プロパティ名は IsMovable です。In the example, the attached property name is IsMovable. したがって、アクセサーの名前は GetIsMovableSetIsMovable にする必要があります。Therefore, the accessors must be named GetIsMovable and SetIsMovable. 添付プロパティの所有者は GameService という名前の独自の UI を持たないサービス クラスです。その目的は GameService.IsMovable 添付プロパティを使うときに、添付プロパティ サービスを提供することだけです。The owner of the attached property is a service class named GameService that doesn't have a UI of its own; its purpose is only to provide the attached property services when the GameService.IsMovable attached property is used.

添付プロパティを定義する、c++/cli CX は少し複雑です。Defining the attached property in C++/CX is a bit more complex. ヘッダーとコード ファイル間の関連性を決定する必要があります。You have to decide how to factor between the header and code file. また、「カスタム依存関係プロパティ」で説明している理由から、識別子を get アクセサーのみ持つプロパティとして公開する必要があります。Also, you should expose the identifier as a property with only a get accessor, for reasons discussed in Custom dependency properties. C++/cli CX のこのプロパティ フィールドのリレーションシップを定義する必要があります .NET に依存するのではなく、明示的にreadonly keywording と単純なプロパティの暗黙のバッキング。In C++/CX you must define this property-field relationship explicitly rather than relying on .NET readonly keywording and implicit backing of simple properties. また、アプリが最初に開始されたとき、添付プロパティを必要とする XAML ページが読み込まれる前に、1 回だけ実行されるヘルパー関数内で、添付プロパティの登録を実行する必要があります。You also need to perform the registration of the attached property within a helper function that only gets run once, when the app first starts but before any XAML pages that need the attached property are loaded. 依存関係プロパティまたは添付プロパティのプロパティ登録ヘルパー関数を呼び出す一般的な場所は、app.xaml ファイルのコードの App / Application コンストラクターの内部からです。The typical place to call your property registration helper functions for any and all dependency or attached properties is from within the App / Application constructor in the code for your app.xaml file.

public class GameService : DependencyObject
{
    public static readonly DependencyProperty IsMovableProperty = 
    DependencyProperty.RegisterAttached(
      "IsMovable",
      typeof(Boolean),
      typeof(GameService),
      new PropertyMetadata(false)
    );
    public static void SetIsMovable(UIElement element, Boolean value)
    {
        element.SetValue(IsMovableProperty, value);
    }
    public static Boolean GetIsMovable(UIElement element)
    {
        return (Boolean)element.GetValue(IsMovableProperty);
    }
}
Public Class GameService
    Inherits DependencyObject

    Public Shared ReadOnly IsMovableProperty As DependencyProperty = 
        DependencyProperty.RegisterAttached("IsMovable",  
        GetType(Boolean), 
        GetType(GameService), 
        New PropertyMetadata(False))

    Public Shared Sub SetIsMovable(ByRef element As UIElement, value As Boolean)
        element.SetValue(IsMovableProperty, value)
    End Sub

    Public Shared Function GetIsMovable(ByRef element As UIElement) As Boolean
        GetIsMovable = CBool(element.GetValue(IsMovableProperty))
    End Function
End Class
// GameService.idl
namespace UserAndCustomControls
{
    [default_interface]
    runtimeclass GameService : Windows.UI.Xaml.DependencyObject
    {
        GameService();
        static Windows.UI.Xaml.DependencyProperty IsMovableProperty{ get; };
        static Boolean GetIsMovable(Windows.UI.Xaml.DependencyObject target);
        static void SetIsMovable(Windows.UI.Xaml.DependencyObject target, Boolean value);
    }
}

// GameService.h
...
    static Windows::UI::Xaml::DependencyProperty IsMovableProperty() { return m_IsMovableProperty; }
    static bool GetIsMovable(Windows::UI::Xaml::DependencyObject const& target) { return winrt::unbox_value<bool>(target.GetValue(m_IsMovableProperty)); }
    static void SetIsMovable(Windows::UI::Xaml::DependencyObject const& target, bool value) { target.SetValue(m_IsMovableProperty, winrt::box_value(value)); }

private:
    static Windows::UI::Xaml::DependencyProperty m_IsMovableProperty;
...

// GameService.cpp
...
Windows::UI::Xaml::DependencyProperty GameService::m_IsMovableProperty =
    Windows::UI::Xaml::DependencyProperty::RegisterAttached(
        L"IsMovable",
        winrt::xaml_typename<bool>(),
        winrt::xaml_typename<UserAndCustomControls::GameService>(),
        Windows::UI::Xaml::PropertyMetadata{ winrt::box_value(false) }
);
...
// GameService.h
#pragma once

#include "pch.h"
//namespace WUX = Windows::UI::Xaml;

namespace UserAndCustomControls {
    public ref class GameService sealed : public WUX::DependencyObject {
    private:
        static WUX::DependencyProperty^ _IsMovableProperty;
    public:
        GameService::GameService();
        void GameService::RegisterDependencyProperties();
        static property WUX::DependencyProperty^ IsMovableProperty
        {
            WUX::DependencyProperty^ get() {
                return _IsMovableProperty;
            }
        };
        static bool GameService::GetIsMovable(WUX::UIElement^ element) {
            return (bool)element->GetValue(_IsMovableProperty);
        };
        static void GameService::SetIsMovable(WUX::UIElement^ element, bool value) {
            element->SetValue(_IsMovableProperty,value);
        }
    };
}

// GameService.cpp
#include "pch.h"
#include "GameService.h"

using namespace UserAndCustomControls;

using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Documents;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;

GameService::GameService() {};

GameService::RegisterDependencyProperties() {
    DependencyProperty^ GameService::_IsMovableProperty = DependencyProperty::RegisterAttached(
         "IsMovable", Platform::Boolean::typeid, GameService::typeid, ref new PropertyMetadata(false));
}

XAML マークアップからカスタム添付プロパティの設定Setting your custom attached property from XAML markup

注意

C + を使用している場合/cli WinRT をクリックし、次のセクションに進みます (強制的に、カスタム添付プロパティを設定するには C +/cli WinRT)。If you're using C++/WinRT, then skip to the following section (Setting your custom attached property imperatively with C++/WinRT).

添付プロパティを定義し、そのサポート メンバーをカスタム型の一部として含めたら、定義を XAML で利用できるようにする必要があります。After you have defined your attached property and included its support members as part of a custom type, you must then make the definitions available for XAML usage. そのためには、関連クラスを含むコード名前空間を参照する XAML 名前空間をマップする必要があります。To do this, you must map a XAML namespace that will reference the code namespace that contains the relevant class. 添付プロパティをライブラリの一部として定義した場合は、そのライブラリをアプリのアプリ パッケージの一部として含める必要があります。In cases where you have defined the attached property as part of a library, you must include that library as part of the app package for the app.

XAML の XML 名前空間マッピングは、通常は XAML ページのルート要素に配置されます。An XML namespace mapping for XAML is typically placed in the root element of a XAML page. たとえば、前のスニペットで示した添付プロパティ定義を含む名前空間 UserAndCustomControlsGameService という名前のクラスがある場合、マッピングは次のようになります。For example, for the class named GameService in the namespace UserAndCustomControls that contains the attached property definitions shown in preceding snippets, the mapping might look like this.

<UserControl
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:uc="using:UserAndCustomControls"
  ... >

マッピングを使うと、Windows ランタイムで定義された既にある型も含め、ターゲット定義に一致する任意の要素に GameService.IsMovable 添付プロパティを設定できます。Using the mapping, you can set your GameService.IsMovable attached property on any element that matches your target definition, including an existing type that Windows Runtime defines.

<Image uc:GameService.IsMovable="True" .../>

同じマップされた XML 名前空間内にもある要素にプロパティを設定する場合でも、添付プロパティ名にプレフィックスを含める必要があります。If you are setting the property on an element that is also within the same mapped XML namespace, you still must include the prefix on the attached property name. これは、プレフィックスによって所有者型が修飾されるためです。This is because the prefix qualifies the owner type. 標準 XML 規則により属性が要素から名前空間を継承できる場合でも、添付プロパティの属性がその属性を含む要素と同じ XML 名前空間にあることは想定できません。The attached property's attribute cannot be assumed to be within the same XML namespace as the element where the attribute is included, even though, by normal XML rules, attributes can inherit namespace from elements. たとえば、GameService.IsMovableImageWithLabelControl のカスタム型 (定義は示しません) に設定する場合、その両方が同じプレフィックスにマップされる同じコード名前空間に定義されていても、XAML は依然として次のようになります。For example, if you are setting GameService.IsMovable on a custom type of ImageWithLabelControl (definition not shown), and even if both were defined in the same code namespace mapped to same prefix, the XAML would still be this.

<uc:ImageWithLabelControl uc:GameService.IsMovable="True" .../>

注意

C + と XAML の UI を作成するかどうかは/cli CX、しを含める必要があります、添付プロパティを任意の時点を定義するカスタム型のヘッダー XAML ページがその型を使用します。If you are writing a XAML UI with C++/CX, then you must include the header for the custom type that defines the attached property, any time that a XAML page uses that type. 各 XAML ページは、関連付けられているコード ビハインド ヘッダー (. xaml.h)。Each XAML page has an associated code-behind header (.xaml.h). これは、含める必要がある (を使用して #含める) 添付プロパティの所有者の種類の定義のヘッダー。This is where you should include (using #include) the header for the definition of the attached property's owner type.

C + 強制的に、カスタム添付プロパティを設定/cli WinRTSetting your custom attached property imperatively with C++/WinRT

C + を使用している場合/cli は XAML マークアップからではなく、命令型コードからは、WinRT 後からカスタム添付プロパティにアクセスすることができます。If you're using C++/WinRT, then you can access a custom attached property from imperative code, but not from XAML markup. 次のコード方法。The code below shows how.

<Image x:Name="gameServiceImage"/>
// MainPage.h
...
#include "GameService.h"
...

// MainPage.cpp
...
MainPage::MainPage()
{
    InitializeComponent();

    GameService::SetIsMovable(gameServiceImage(), true);
}
...

カスタム添付プロパティの値型Value type of a custom attached property

カスタム添付プロパティの値型として使われる型は、使用方法、定義、または使用方法と定義の両方に影響します。The type that is used as the value type of a custom attached property affects the usage, the definition, or both the usage and definition. 添付プロパティの値型は、複数の場所で (Get アクセサー メソッドと Set アクセサー メソッド両方のシグネチャで、また RegisterAttached 呼び出しの propertyType パラメーターとして) 宣言されます。The attached property's value type is declared in several places: in the signatures of both the Get and Set accessor methods, and also as the propertyType parameter of the RegisterAttached call.

添付プロパティ (カスタムまたはそれ以外) で最も一般的な値型は、単純な文字列です。The most common value type for attached properties (custom or otherwise) is a simple string. これは、添付プロパティは一般に XAML 属性で使われることが意図されており、文字列を値型として使うとプロパティが軽量になるためです。This is because attached properties are generally intended for XAML attribute usage, and using a string as the value type keeps the properties lightweight. 整数、倍精度浮動小数点、列挙値など、文字列メソッドへのネイティブ変換を持つその他のプリミティブも、添付プロパティの値型として一般的です。Other primitives that have native conversion to string methods, such as integer, double, or an enumeration value, are also common as value types for attached properties. ネイティブ文字列変換をサポートしない他の値型を添付プロパティ値として使うこともできます。You can use other value types—ones that don't support native string conversion—as the attached property value. ただし、その場合は、使用方法または実装について選択が必要です。However, this entails making a choice about either the usage or the implementation:

  • 添付プロパティはそのままにすることができますが、添付プロパティでは、添付プロパティがプロパティ要素であり、値がオブジェクト要素として宣言される使用方法のみサポートできます。You can leave the attached property as it is, but the attached property can support usage only where the attached property is a property element, and the value is declared as an object element. この場合、プロパティ型はオブジェクト要素としての XAML の使用をサポートする必要があります。In this case, the property type does have to support XAML usage as an object element. 既にある Windows ランタイム参照クラスの場合は、XAML 構文を調べて、型が XAML オブジェクト要素の使用をサポートすることを確認します。For existing Windows Runtime reference classes, check the XAML syntax to make sure that the type supports XAML object element usage.
  • 添付プロパティはそのままにすることができますが、文字列として表現できる BindingStaticResource などの XAML 参照手法で属性を使う場合にのみ使います。You can leave the attached property as it is, but use it only in an attribute usage through a XAML reference technique such as a Binding or StaticResource that can be expressed as a string.

Canvas.Left の例に関する詳細More about the Canvas.Left example

添付プロパティの使用法として前に挙げた例では、Canvas.Left 添付プロパティを設定するさまざまな方法を説明しました。In earlier examples of attached property usages we showed different ways to set the Canvas.Left attached property. しかし、それによって Canvas がオブジェクトとやり取りする方法やタイミングがどのように変わるのでしょうか。But what does that change about how a Canvas interacts with your object, and when does that happen? ここでは、この例をさらに詳しく検討します。添付プロパティを実装しており、他のオブジェクトで添付プロパティの値が検出された場合に、典型的な添付プロパティの所有者クラスが添付プロパティの値に対して実行する処理を理解するのは意味のあることだからです。We'll examine this particular example further, because if you implement an attached property, it's interesting to see what else a typical attached property owner class intends to do with its attached property values if it finds them on other objects.

Canvas の主な機能は、UI で絶対位置の決まったレイアウト コンテナーとなることです。The main function of a Canvas is to be an absolute-positioned layout container in UI. Canvas の子は、基底クラスの定義済みプロパティ Children に格納されます。The children of a Canvas are stored in a base-class defined property Children. パネルのうち、Canvas だけが絶対配置を使います。Of all the panels Canvas is the only one that uses absolute positioning. Canvas や特定の UIElementUIElement の子要素になっている場合にのみ関係するプロパティを追加した場合には、共通の UIElement 型のオブジェクト モデルが大きくなっていたおそれがあります。It would've bloated the object model of the common UIElement type to add properties that might only be of concern to Canvas and those particular UIElement cases where they are child elements of a UIElement. Canvas のレイアウト コントロールのプロパティを、どの UIElement でも使用できる添付プロパティに定義すると、オブジェクト モデルをすっきりした状態に保つことができます。Defining the layout control properties of a Canvas to be attached properties that any UIElement can use keeps the object model cleaner.

Canvas にはパネルを実用的にするため、フレームワーク レベルの MeasureArrange メソッドを上書きするという動作があります。In order to be a practical panel, Canvas has behavior that overrides the framework-level Measure and Arrange methods. Canvas が子について実際に添付プロパティを確認するのはここです。This is where Canvas actually checks for attached property values on its children. MeasureArrange の両パターンの一部は、コンテンツを反復処理するループです。また、パネルには、パネルの子とされるものを明確にする Children プロパティがあります。Part of both the Measure and Arrange patterns is a loop that iterates over any content, and a panel has the Children property that makes it explicit what's supposed to be considered the child of a panel. このため、Canvas レイアウトの動作は、子を反復処理したうえで、子のそれぞれについて Canvas.GetLeftCanvas.GetTop の静的呼び出しを実行し、その添付プロパティに既定以外の値 (既定値は 0) が含まれているかどうかを確認するというものになります。So the Canvas layout behavior iterates through these children, and makes static Canvas.GetLeft and Canvas.GetTop calls on each child to see whether those attached properties contain a non-default value (default is 0). 確認された値はその後、Canvas の利用可能なレイアウト スペースで子のそれぞれが提供する値に応じて、子の絶対位置を設定するのに使われた後、Arrange を使ってコミットされます。These values are then used to absolutely position each child in the Canvas available layout space according to the specific values provided by each child, and committed using Arrange.

コードは、次の擬似コードのようになります。The code looks something like this pseudocode.

protected override Size ArrangeOverride(Size finalSize)
{
    foreach (UIElement child in Children)
    {
        double x = (double) Canvas.GetLeft(child);
        double y = (double) Canvas.GetTop(child);
        child.Arrange(new Rect(new Point(x, y), child.DesiredSize));
    }
    return base.ArrangeOverride(finalSize); 
    // real Canvas has more sophisticated sizing
}

注意

パネルの動作方法の詳細については、次を参照してください。 XAML カスタム パネルの概要します。For more info on how panels work, see XAML custom panels overview.