アーカイブ

アーカイブ2008

機能の実装でSilverlight時間デザインキット

2008年12月28日 4コメント

導入

これは私のSilverlightのデザイン時の機能シリーズの第2の投稿です。 最初の投稿デザインタイム機能はツールキットでSilverlightのデザイン時の機能を示したSilverlightをツールキットを制御する このポストはどのように実装されて説明します。 うまくいけば、この記事は、私たちのソースコードを説明し、どのようにSilverlightのデザイン時の機能を実装するデモを支援して、直接自分たちのプロジェクトで使用できるフレームワークとソースコードリーダーを提供します。

概要

ダウンロードは、"SilverlightをToolkitは-バイナリ、サンプル、ドキュメント、ユニットテストと"ソース2008年12月リリース 、オープンSourceSilverlight.Controls.sln StudioでのVisual、私たちは、フォルダのソリューションが参照してくださいデザインデザインプロジェクトの下に12があるが、各コントロールの3つのためにアセンブリ。

Silverlight.Controls.sln Visual Studioで

たとえば、コントロールのプロジェクトに乗り、3つの設計プロジェクトがあります:

  • Controls.Designは:Windows.Controls.Design.dll、設計時間を含むビルドは、Visual StudioとExpression Blendで共有しています。
  • Controls.Expression.Designは:Windows.Controls.Expression.Design.dll、唯一のExpression Blendのためのデザイン時の機能が含まれてビルドします。
  • Controls.VisualStudio.Designは:Windows.Controls.VisualStudio.Design.dll、唯一のVisual Studioのデザイン時の機能が含まれてビルドします。

また、2つのファイルを含みます:Design.CommonフォルダがExtensions.csとMetadataBase.cs、すべての設計プロジェクトで共有されます。

これは投稿されてブログを強くお勧めの、あなたが読んでジャスティンエンジェルSilverlightのデザイン時の機能拡張 :それは基づいて実装さでその下、上のSilverlightのデザイン時の機能拡張良い提供しています背景/情報概要。

プロジェクト

全12のデザインプロジェクトが同じ実装のパターンに従って、私はそれらをすべて説明するControl.Designのプロジェクトを使用しますので。

初めてのVisual Studioにソースの下に負荷Silverlight.Controls.slnディレクトリは、我々が表示されます以下のような画面:

Silverlight.Controls.Design.csproj Visual Studioで

  • Controls.Designは、コントロールのプロジェクトにプロジェクトの依存関係があります。 この依存関係は、コントロールプロジェクトを最初にビルドされるように、とControls.DesignはMicrosoft.Windows.Controlsアセンブリコントロールプロジェクトによって構築への参照をしています。 デザイン時のアセンブリは、常にそれを参照のため、デザイン時の機能を提供するランタイムのアセンブリを。
  • Controls.Design参照Microsoft.Windows.Design&Microsoft.Windows.Design.Extensibilityアセンブリ、どちらのディレクトリ%DevEnvDir%のPublicAssemblies(下にあるC:プログラムFilesMicrosoft Visual Studioの9.0Common7IDEPublicAssemblies私のラップトップ)。 デザイン時のアセンブリは、頻繁に参照するデザイナーの機能拡張フレームワークを提供するこれらの2つのアセンブリを、。 常に参照システムアセンブリも、そのCategoryAttributeのようなメタデータの多くの属性System.ComponentModel名前空間は、(含まれている、DescriptionAttribute)定義されてデザイン時のアセンブリ。
  • Controls.Design参照System.Windowsアセンブリ。 我々はあまりにもControls.Design.csprojの参照を見ることができます:

    <reference Include="System.Windows, Version=2.0.5.0、Culture=neutral, PublicKeyToken=7cec85d7bea7798e, processorArchitecture=MSIL">
    / SpecificVersionの> <SpecificVersion>はFalse <
    <HintPath> .. BinariesSystem.Windows.dll </ HintPath>
    /プライベート> <Private>はFalse <
    </リファレンス>

    ご注意:

    • Control.Designは、Windowsクラスライブラリプロジェクトは、Silverlightのプロジェクトではありません。生成Microsoft.Windows.Controls.Design.dll。NETのアセンブリは、Visual StudioまたはExpression Blendのではなく、Silverlightのアセンブリ内で実行のようなデザイナー内のデスクトップ上で実行しているブラウザにもかかわらず、Microsoft.Windows.Controls.Design.dllは、SilverlightランタイムアセンブリMicrosoft.Windows.Controls.dllのデザイン時のアセンブリです。
    • 参照System.Windowsアセンブリは、実際にはSilverlightのアセンブリ(バージョン2.0.5.0)です。 System.Windowsアセンブリは、Silverlightコントロールのすべての設計プロジェクトで必要とされない場合があります。 我々はポスト必要以上かそれ以降で、ここが主な原因のGetMemberName <T>は(表現<FUNC画面について説明します私たちは<T,オブジェクト> Extension.cs>のexpr の)メソッドです 我々はすぐに見るように。NETおよびSilverlight参照のミックスは、興味深い問題のすべての種類を作成します。

      以下のILDASMのスクリーンショットはMicrosoft.Windows.Controls.Design.dllで。NETとSilverlightのアセンブリへの混合の参照を示しています:
      ILDASMのMicrosoft.Windows.Controls.Design.dll Microsoft.Windows.Controls.Designアセンブリはマニフェスト

      • 。バージョン2:0:21024:1838は、Silverlight Toolkitの2008年12月リリースのバージョン番号です。
      • 。バージョン3:5:0:0は、。NETフレームワーク3.5のバージョン番号です。
      • 。バージョン2:0:0:0は、Silverlight 2.0のバージョン番号です。
    • Visual Studioにするときに最初にロードControls.Designプロジェクト、そこにある"参照コンポーネント'System.Windows'が見つかりませんでした"という警告がプロジェクトウィンドウにSystem.Windowsアセンブリ参照の横にある[エラー一覧]ウィンドウでも。 Silverlightの代わりにこれはプロジェクトですので、Controls.Designがあります。NETの、私たちは言語:Cの下にしないと、知っている場所がインストールされSilverlightは(C:プログラムの下では、FilesMicrosoftのSilverlight2.0.31005.0私のラップトッププログラムファイル(x86の)私のデスクトップ上のMicrosoft Silverlight2.0.31005.0)。 解決策は、事前にそのコピーSystem.Windows.dllは、Silverlightから..バイナリへの方向をインストールするイベントコマンド.. CopySystemWindows.batを構築することです。 我々はすぐに見るようにだから、一度プロジェクトをビルドしたら、警告が離れて行きます。
  • Visual Studioのスクリーンショットでは、上記の、別の警告サインプロジェクトの未亡人、初めてのVisual Studioには、負荷Controls.Designプロジェクト内のファイルMicrosoft.Windows.Controls.XML隣にあります。 このファイルは、依存コントロールプロジェクトを構築することによって、コントロールプロジェクトのプロパティのために生成されます - >ビルド]タブをクリック、オプションの"XMLドキュメントファイル"をチェックされ、"..ビナーのパスを持つ
    あなたはControls.Designプロジェクトをビルドする場合我々はまもなく見るようにiesMicrosoft.Windows.Controls.XML"は、警告が離れて行きます。
  • Controls.Designプロジェクトでは、Metadata.csファイルがあるとDesign.CommonフォルダにExtension.csとMetadataBase.csへのリンク。 全12デザインプロジェクトは、これらの3つのファイルがあります。 我々は、より詳細に、後でそれを説明します。

ビルドControls.Designのプロジェクトまたはソリューション全体が、我々が見ることができます:

Silverlight.Control.slnのビルド出力

  • すべてのプロジェクトはうまく0のエラーと警告0で構築された。
  • 警告サインがSystem.Windows参照し、次の消失ファイルMicrosoft.Windows.Controls.XML。
  • ビルドプロセスのコード分析は、長い時間がかかる、それは2つの警告を生成します。 1つ目は、CA0060は、混合の別の問題です。NETおよびSilverlightの参照とExtension.csのコードです。 あなたは、警告のSilverlightのインストールディレクトリからSourceBinariesディレクトリと建物に再びSystem.dllおよびSystem.Core.dllをコピーして取り除くことができます。

MetadataBase.cs

MetadataBase.cs、一緒にMetadata.csで、設計時のメタデータの登録のための枠組みを実装する:

  • DescriptionAttributesは自動的にパブリックコントロールクラスの(生成されるすなわち、FrameworkElementはのサブクラス)と"/ / /"はソースコード内のXMLドキュメントのコメント<summary>からのパブリックプロパティ。 (グッドはコメントの投稿は支払う! :-)
  • デザイナからコントロールクラスを非表示にAddAttributesメソッドへのプロジェクトのMetadata.csで以下のような行を追加するには:
    (builder.AddCallback typeof演算(TreeViewItemの)、b => b.AddCustomAttributes(新しいToolboxBrowsableAttribute(偽)));
  • コントロールクラスの他のカスタム属性を登録すると、XxxMetadata.csを追加するプロジェクトに、ViewboxMetadata.cs後述のようにします。

ようなフレームワークの場合は、対象のプロジェクト、することができますMetadata.csを使用してMetadataBase.cs、直接あなたのMicrosoft Public Licenseのファイルのソースのすべての私達のの含まれてで始まり。

MetadataBase.cs:

 System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Windows; using System.Xml.Linq; using Microsoft.Windows.Design.Metadata; namespace Microsoft.Windows.Controls.Design.Common { /// <summary> /// MetadataRegistration class. /// </summary> public class MetadataRegistrationBase { /// <summary> /// Build design time metadata attribute table. /// </summary> /// <returns>Custom attribute table.</returns> protected virtual AttributeTable BuildAttributeTable() { AttributeTableBuilder builder = new AttributeTableBuilder(); AddDescriptions(builder); AddAttributes(builder); AddTables(builder); return builder.CreateTable(); } /// <summary> /// Find all AttributeTableBuilder subclasses in the assembly /// and add their attributes to the assembly attribute table. /// </summary> /// <param name="builder">The assembly attribute table builder.</param> [SuppressMessage( "Microsoft.Design" , "CA1031:DoNotCatchGeneralExceptionTypes" , Justification = "Design time dll should not fail!" )] private static void AddTables(AttributeTableBuilder builder) { Debug.Assert(builder != null , "AddTables is called with null parameter!" ); Assembly asm = Assembly.GetExecutingAssembly(); foreach (Type t in asm.GetTypes()) { if (t.IsSubclassOf( typeof (AttributeTableBuilder))) { try { AttributeTableBuilder atb = (AttributeTableBuilder)Activator.CreateInstance(t); builder.AddTable(atb.CreateTable()); } catch (Exception e) { Debug.Assert( false , string .Format(CultureInfo.InvariantCulture, "Exception in AddTables method: {0}" , e)); } } } } /// <summary> /// Gets or sets the case sensitive resource name of the embedded XML file. /// </summary> protected string XmlResourceName { get; set; } /// <summary> /// Gets or sets the assembly FullName for types' assembly-qualified names. /// </summary> protected string AssemblyFullName { get; set; } /// <summary> /// Create description attribute from run time assembly xml file. /// </summary> /// <param name="builder">The assembly attribute table builder.</param> [SuppressMessage( "Microsoft.Design" , "CA1031:DoNotCatchGeneralExceptionTypes" , Justification = "Design time dll should not fail." )] private void AddDescriptions(AttributeTableBuilder builder) { Debug.Assert(builder != null , "AddDescriptions is called with null parameter!" ); if ( string .IsNullOrEmpty(XmlResourceName) || string .IsNullOrEmpty(AssemblyFullName)) { return ; } XDocument xdoc = XDocument.Load( new StreamReader( Assembly.GetExecutingAssembly().GetManifestResourceStream(XmlResourceName))); if (xdoc == null ) { return ; } foreach (XElement member in xdoc.Descendants( "member" )) { try { string name = ( string )member.Attribute( "name" ); bool isType = name.StartsWith( "T:" , StringComparison.OrdinalIgnoreCase); if (isType || name.StartsWith( "P:" , StringComparison.OrdinalIgnoreCase)) { int lastDot = name.Length; string typeName; if (isType) { typeName = name.Substring(2); } else { lastDot = name.LastIndexOf( '.' ); typeName = name.Substring(2, lastDot - 2); } typeName += AssemblyFullName; Type t = Type.GetType(typeName); if (t != null && t.IsPublic && t.IsClass && t.IsSubclassOf( typeof (FrameworkElement))) { string desc = member.Descendants( "summary" ).FirstOrDefault().Value; desc = desc.Trim(); desc = string .Join( " " , desc.Split( new char [] { ' ' , 't' , 'n' }, StringSplitOptions.RemoveEmptyEntries)); if (isType) { builder.AddCallback(t, b => b.AddCustomAttributes( new DescriptionAttribute(desc))); } else { string propName = name.Substring(lastDot + 1); PropertyInfo pi = t.GetProperty(propName); MethodInfo mi; if (pi != null && (mi = pi.GetSetMethod()) != null && mi.IsPublic) { builder.AddCallback(t, b => b.AddCustomAttributes(propName, new DescriptionAttribute(desc))); } } } } } catch (Exception e) { Debug.Assert( false , string .Format(CultureInfo.InvariantCulture, "Exception in AddDescriptions method: {0}" , e)); } } } /// <summary> /// Provide a place to add custom attributes without creating a AttributeTableBuilder subclass. /// </summary> /// <param name="builder">The assembly attribute table builder.</param> protected virtual void AddAttributes(AttributeTableBuilder builder) { } } } / /(c)の著作権Microsoft Corporationのは/ /このソース)のPL -れている件名に、Microsoft Public Licenseの(さん/ /詳細については、http://go.microsoft.com/fwlink/?LinkID=131993を参照してください。/ /他のすべての権利を保有。システムを使用して、System.Collections.Genericを使用して、System.ComponentModelを使用して、 ください 。using System.Diagnostics; System.Diagnostics.CodeAnalysisを使用して、System.Globalizationを使用して、System.IOを使用して、System.Linqを使用して、システムを使用して。Linq.Expressions; します 。using System.Reflection; System.Windowsを使用して、System.Xml.Linqを使用して、Microsoft.Windows.Design.Metadataを使用して、 名前空間 Microsoft.Windows.Controls.Design.Common(/ / / <summary> / / / MetadataRegistrationクラスは、。/ / / <は/概要> パブリッククラス MetadataRegistrationBase(/ / / <summary> / / /ビルド設計時のメタデータは、テーブルの属性/ / / <returns>カスタム属性テーブル/ / / </概要>。<を/を返しますが)(> 保護仮想 AttributeTable BuildAttributeTable()(AttributeTableBuilderビルダー= 新しい AttributeTableBuilder; AddDescriptions(ビルダーを); AddAttributes(ビルダーを); AddTables(ビルダーを); 下さい 返す builder.CreateTable();)/ / / <summary> / / /は、内のアセンブリのサブクラスのすべてのAttributeTableBuilderの/ / /、テーブルのアセンブリ属性の追加の属性を/ / / </概要> / / / <paramのname="builder">アセンブリ属性テーブルビルダを。</パラメータ> [SuppressMessage( "Microsoft.Designは"、"CA1031:DoNotCatchGeneralExceptionTypes"、正当化="デザイン時のDLLは、失敗しないでください!")] プライベート静的ボイド AddTablesを(AttributeTableBuilderビルダー)(Debug.Assertの(ビルダー!= nullの場合、"AddTablesはパラメータがNULLと呼ばれる!");国会のasm = Assembly.GetExecutingAssembly()は、asm.GetTypes foreachの tを入力 (())( 場合(t.IsSubclassOf(typeof演算 (AttributeTableBuilder)))(( しよう )Activator.CreateInstanceを(AttributeTableBuilderのATBをを=(AttributeTableBuilder t)は、builder.AddTable(atb.CreateTable());) キャッチ (例外電子)(Debug.Assertの(falseの場合、 文字列です 。形式は(CultureInfo.InvariantCulture、"例外メソッドでAddTablesの:(0)"、電子)); ))))/ / / <summary> / / /を取得またはファイル埋め込みXML名をのリソース設定大文字小文字を区別/ / / </概要>(保護 文字列XmlResourceNameを取得または設定します;)/ / / <summary> / / /を取得または名前のアセンブリ修飾'設定アセンブリのFullNameのために型/ / / </概要>(保護の文字列AssemblyFullNameを取得または設定します;)/ / / <summary> / / /を作成する説明属性ファイルから実行時にアセンブリのxmlパラメータ> [SuppressMessage("Microsoft.Design"。/ / / </概要>は、/ / / <paramのname="builder">アセンブリ属性テーブルビルダ。</、"CA1031:DoNotCatchGeneralExceptionTypes"、正当化=" デザイン時のdll失敗しないでください。")] します。private void AddDescriptionsを(AttributeTableBuilderビルダー)(Debug.Assertの(ビルダー!= nullの場合、"AddDescriptionsはパラメータがNULLと呼ばれる!"); 場合文字列です 。IsNullOrEmpty(XmlResourceName)| | 文字列です 。IsNullOrEmpty(AssemblyFullName ))( を返す ;)のXDocument xdocを= XDocument.Load( 新しい StreamReaderを(Assembly.GetExecutingAssembly()。GetManifestResourceStream(XmlResourceName))); 返す場合 (xdocは== nullが )(;)xdoc.Descendants foreachのメンバー XElementオブジェクトの(("メンバーは"))(; しようとする のT:"、StringComparison.OrdinalIgnoreCase)( 文字列 =( 文字列 )member.Attribute("名前"); ブール isType = name.StartsWith(" 場合 (isType | | name.StartsWith( の"P :"、StringComparison.OrdinalIgnoreCase))(int lastDot = name.Length; 文字列 typeNameは、 場合 (isType)(typeNameは= name.Substring(2);)  (lastDot = name.LastIndexOf(''); typeNameは=名。部分文字列(2、lastDot - 2);)typeNameは+ = AssemblyFullName;タイプトン= Type.GetType(typeNameは); 場合 (トン!= nullの&t.IsPublic&t.IsClass&t.IsSubclassOf(typeof演算 (FrameworkElementは)) )( 文字列降順= member.Descendants("要約")。FirstOrDefault()。適正; 文字列です 。参加降順= desc.Trim();降順=(""、(desc.Split 新しいchar [](''、'トン'、'n'を )、StringSplitOptions.RemoveEmptyEntries)); 場合 (isType)(builder.AddCallback(トン、b => b.AddCustomAttributes( 新しい DescriptionAttribute(降順)));) 文字列属性名= name.Substring( lastDot + 1);のPropertyInfoπ= t.GetProperty(属性名); MethodInfoミ; 場合(π!= nullの&&(マイル= pi.GetSetMethod())!= nullの&mi.IsPublic)(builder.AddCallback(トン、b => b.AddCustomAttributes(属性名は、 新しい DescriptionAttribute(降順)));))))): キャッチ (例外電子)(Debug.Assertの(falseの場合、 文字列です 。形式(CultureInfo.InvariantCulture、"AddDescriptions例外のメソッド(0) "、電子));)))/ / / <summary> / / /サブクラスを提供AttributeTableBuilderのなく作成属性をカスタムの場所を追加します。> / / / <paramのname="builder"> / / / </概要アセンブリ属性テーブルビルダ。</パラメータの>)が 保護される仮想無効 AddAttributesを(AttributeTableBuilderビルダー())) 

MetadataBase.csはMetadataRegistrationBaseクラスを実装します。 のいくつかの主要なメソッドを説明してみましょう:

AddDescriptions

すべての実行時にアセンブリのプロジェクトは、"XMLドキュメントファイル"オプションをチェックし、BinariesMicrosoft.Windows.Controls.XML""..のようなパスは、プロジェクトに - >プロパティ - >ビルド]タブをクリック、出力セクションがあります。 また、の設定を見つけることができます。csprojファイルを以下のように:

  > ..BinariesMicrosoft.Windows.Controls.Design.XML </ DocumentationFile > <DocumentationFile> .. BinariesMicrosoft.Windows.Controls.Design.XML </ DocumentationFile> 

以下は、Microsoft.Windows.Controls.XMLの抜粋か生成されたドキュメントは次のようにXMLファイルを表示することです:

  version ="1.0" ? > <?xml バージョン ="1.0"?>
 > < ドキュメント >
     > < 組立 >
         > Microsoft.Windows.Controls </ name > < 名前 > Microsoft.Windows.Controls </  >
     > </ アセンブリ >
     > < メンバー  >
         name ="T:Microsoft.Windows.Controls.Viewbox" > < メンバー  ="のT:Microsoft.Windows.Controls.Viewbox">
             > < 概要 >
            定義伸ばすことができると、単一の子を拡張コンテンツデコレータ
            利用可能なスペースをご記入ください。
             > </ サマリー >
             > Preview </ QualityBand > <は> <を/ QualityBand QualityBand>プレビュー
         > </ メンバー >
         name ="F:Microsoft.Windows.Controls.Viewbox.ChildElementName" > < メンバー  =の"F:Microsoft.Windows.Controls.Viewbox.ChildElementName">
             > < 概要 >
             Viewboxののデフォルトの子要素の名前のテンプレート。
             > </ サマリー >
         > </ メンバー >
         name ="M:Microsoft.Windows.Controls.Viewbox.IsValidStretchValue(System.Object)" > < メンバー  ="M日付:Microsoft.Windows.Controls.Viewbox.IsValidStretchValue(System.Objectの)">
             > < 概要 >
            かどうかをオブジェクトの値に渡された有効なストレッチ列挙型の値を確認します。
             > </ サマリー >
             name ="o" > The object typed value to be checked. </ param > <  param の名前は ="o"が>します。< パラメータの /チェックする>オブジェクトを指定された値を
             > True if o is a valid Stretch enum value, false o/w. </ returns > <は> を返します返します >/列挙型の値はfalseオ/ワットの<oが有効なストレッチ
         > </ メンバー >
         name ="P:Microsoft.Windows.Controls.Viewbox.Child" > < メンバー 名は、= の"P:Microsoft.Windows.Controls.Viewbox.Child">
             > < 概要 >
            取得またはViewboxの1つの子要素を設定します。
             > </ サマリー >
         > </ メンバー >
     > </ メンバー >
 > </ docに> 

各<member>要素のname属性は、パターンを次の:

  • の"T:Microsoft.Windows.Controls.Viewbox":"のT:"これは型、型の完全な名前が続いていることを示します。
  • の"F:Microsoft.Windows.Controls.Viewbox.ChildElementName":"Fは:"を示して、このフィールドは、フィールドの完全修飾名が続いている。
  • "Mは:Microsoft.Windows.Controls.Viewbox.IsValidStretchValue(System.Objectの)":"M日付:"を示してこのメソッドは、メソッドの完全修飾名とパラメータが続いている。
  • "Pは:Microsoft.Windows.Controls.Viewbox.Child":の"P:"このプロパティは、プロパティの完全な名前が続いていることを示します。

Microsoft.Windows.Controls.XMLファイルにControl.Designプロジェクトのリンク埋め込まれたリソースとして:

  • Microsoft.Windows.Controls.XMLは、埋め込みリソースを
  • Controls.Design.csproj:

      Include ="..BinariesMicrosoft.Windows.Controls.XML" /> <の EmbeddedResourceは = を含める ".. BinariesMicrosoft.Windows.Controls.XML"/> 

AddDescriptionsメソッドは、埋め込まれたXMLファイルを解析し、公共のコントロールクラスとそのパブリックプロパティのDescriptionAttributeを生成します:

  MetadataBase.cs:134:builder.AddCallback(トン、b => b.AddCustomAttributes( 新しい DescriptionAttribute(降順)));
 MetadataBase.cs:143:builder.AddCallback(トン、b => b.AddCustomAttributes(属性名、 新しい DescriptionAttribute(降順))); 
AddAttributes

AddAttributesは通常Metadata.csでオーバーライドさは追加するファイルToolboxBrowsableAttribute(false)をデザイナのツールボックスに表示されない必要がありますコントロールクラスのカスタム属性:

  • コントロールクラスは、すべてのデザイナーから、ToolboxBrowsableAttribute(false)をXxx.Designプロジェクトにカスタム属性を追加する非表示にする必要がある場合。
  • これは、Visual Studioから隠さ必要がある場合のみ、Xxx.VisualStudio.Designプロジェクトにカスタム属性を追加します。
  • それはExpression Blendのから隠さ必要がある場合のみ、Xxx.Expression.Designプロジェクトにカスタム属性を追加します。

以下は、Metadata.cs Controls.VisualStudio.DesignプロジェクトのAddAttributesの実装です:

  / / / <summary>
 / / /サブクラスを提供AttributeTableBuilderのなく作成属性をカスタムの場所を追加します。
 / / / </概要>
 / / / <paramのname="builder">アセンブリ属性テーブルビルダを。</パラメータの>
 保護されたオーバーライド無効 AddAttributes(AttributeTableBuilderビルダ)

     ToolboxBrowsableAttribute( false ))); (builder.AddCallback typeof演算 (TreeViewItemの)、b => b.AddCustomAttributes( 新しい ToolboxBrowsableAttribute(  )));
 
AddTables

型の属性をToolboxBrowsableAttribute(偽)以外の追加XxxMetadata.csを追加するには適切な設計プロジェクトには、以下ViewboxMetadata.csのようなファイル:

ViewboxMetadata.cs:

  / /(c)の著作権マイクロソフト株式会社。
 / /このソースは)さんは被写体に、Microsoft Public Licenseの(のPL。
 / /詳細については、http://go.microsoft.com/fwlink/?LinkID=131993を参照してください。
 / /他のすべての権利を保有。

 System.ComponentModelを使用して;
 Microsoft.Windows.Controls.Design.Common 使用して ;
 Microsoft.Windows.Design.Metadataを使用して;

 名前空間 Microsoft.Windows.Controls.Design

     / / / <summary>
     / / / Viewboxのためのデザイン時にメタデータを登録してください。
     / / / </概要>
     内部クラス ViewboxMetadata:AttributeTableBuilder
    
         / / / <summary>
         / / / Viewboxのためのデザイン時にメタデータを登録してください。
         / / / </概要>
         公共 ViewboxMetadata()
            ベース ()
        
            から呼び出し(
                 typeof演算 (Viewboxの)
                 b =>
                
                     )); b.AddCustomAttributes(Extensions.GetMemberName <Viewbox>が(x => x.BorderThickness)、 新しい BrowsableAttribute(  ));
                     )); b.AddCustomAttributes(Extensions.GetMemberName <Viewbox>が(x => x.BorderBrush)、 新しい BrowsableAttribute(  ));
                     )); b.AddCustomAttributes(Extensions.GetMemberName <Viewbox>が(x => x.Background)、 新しい BrowsableAttribute(  ));
                     )); b.AddCustomAttributes(Extensions.GetMemberName <Viewbox>が(x => x.Foreground)、 新しい BrowsableAttribute(  ));

                     b.AddCustomAttributes(Extensions.GetMemberName <Viewbox>が(x => x.Child)、 新しい CategoryAttribute(Properties.Resources.CommonProperties));
                     b.AddCustomAttributes(Extensions.GetMemberName <Viewbox>が(x => x.Stretch)、 新しい CategoryAttribute(Properties.Resources.CommonProperties));
                     b.AddCustomAttributes(Extensions.GetMemberName <Viewbox>が(x => x.StretchDirection)、 新しい CategoryAttribute(Properties.Resources.CommonProperties));
                 ));
        
    
 
  • これは、ここでの命名規則に従うことをお勧めします。 たとえば、Viewboxのに乗り、ファイル名はViewboxMetadata.csであり、クラス名はViewboxMetadataです。
  • メタデータクラスには、AttributeTableBuilderから継承する必要があります。
  • あなたは、メタデータクラスのコンストラクタにカスタム属性を追加することができます:
    • あなたが戻って(直販モデル上ViewboxMetada.csの場合)または、モデルのいずれかの呼び出しを使用できます。 コールバックモデルは、おそらく効率的です。
      • 直販モデルの例:

        AddCustomAttributes(

        typeof演算(Viewboxの)、/ /タイプ

        "BorderThickness"、/ /プロパティ名

        新しい属性[](新しいBrowsableAttribute(false)を)); / /カスタム属性の配列

    • AddCustomAttributeコールするプロパティ名のパラメータを提供するために、いずれかのViewboxMetadata.csのように方法のExtensions.GetMemberName()を使用することができます(詳細は約記事の後半で)型安全な方法で、プロパティ名を取得し、又は提供discuss will直販モデルの実装上の"BorderThickness"のような文字列としてプロパティ名を直接。

AddTables(AttributeTableBuilderビルダ)メソッド:

  • 実行中のアセンブリのAttributeTableBuilderのすべてのサブクラスを列挙する
  • 各見つかりましたAttributeTableBuilderサブクラスのインスタンスを作成します:

    AttributeTableBuilderのATBを=(AttributeTableBuilder)Activator.CreateInstanceを(t)は;

  • ビルダに見つかったクラスの属性テーブルを追加します:

    )builder.AddTable(atb.CreateTable();

Metadata.cs

Metadata.csはMetadataRegistrationBaseクラスMetadataBase.csで実装から継承MetadataRegistrationクラスを実装します。 また、実装IRegisterMetadataのインターフェイスです。

Metadata.cs:

  / /(c)の著作権マイクロソフト株式会社。
 / /このソースは)さんは被写体に、Microsoft Public Licenseの(のPL。
 / /詳細については、http://go.microsoft.com/fwlink/?LinkID=131993を参照してください。
 / /他のすべての権利を保有。

 します 。using System.Reflection;
 Microsoft.Windows.Controls.Design.Common 使用して ;
 Microsoft.Windows.Design.Metadataを使用して;

 名前空間 Microsoft.Windows.Controls.Design

     / / / <summary>
     / / / MetadataRegistrationクラス。
     / / / </概要>
     パブリッククラス MetadataRegistration:MetadataRegistrationBase、IRegisterMetadata
    
         / / / <summary>
         / / /デザイン時メタデータ登録クラス。
         / / / </概要>
         公共 MetadataRegistration()
            ベース ()
        
            をAssemblyName asmName = typeof演算 (Viewboxの)。Assembly.GetName();
             XmlResourceNameは= asmName.Name +"の設計。"  + asmName.Name +"XMLと"/ /"Microsoft.Windows.Controls.Design.Microsoft.Windows.Controls.XML"
             AssemblyFullName ="は、"asmName.FullNameを検索する。
        

         / / / <summary>
         / / / System.Windows.Controls.Toolbox.Design.MetadataRegistrationから借用:
         / / /登録確認のメタデータを静的な使用してフラグを1つだけ。
         / / / </概要>
         プライベート静的ブール _initialized;

         / / / <summary>
         / / /メタデータによって呼び出されます時間のデザインツールに登録します。
         / / / </概要>
         公共無効レジスタ()
        
            もし !_initialized)
            
                 MetadataStore.AddAttributeTable(BuildAttributeTable());
                 真の _initialized =;
            
        

         / / / <summary>
         / / /サブクラスを提供AttributeTableBuilderのなく作成属性をカスタムの場所を追加します。
         / / / </概要>
         / / / <paramのname="builder">アセンブリ属性テーブルビルダを。</パラメータの>
         保護されたオーバーライド無効 AddAttributes(AttributeTableBuilderビルダ)
        
        
    
 

の一部を、そのキーの方法について議論してみましょう:

MetadataRegistration

このコンストラクタは2つのキーフィールドを初期化します:

  • XmlResourceNameは:埋め込みドキュメントのリソース名、MetadataRegistrationBase.AddDescriptionsメソッドで使用するXMLファイル。
  • AssemblyFullNameは:実行時にアセンブリの完全な名前、このデザイン時のアセンブリのためです。

あなたは独自のデザインプロジェクトでMetadata.csを使用する場合独自のクラスを持つ型Viewboxのを交換する必要があります。

登録

これが唯一の方法ですIRegisterMetadata インターフェイス これは、AddDescripionsからビルドされ、AddAttributes&AddTables方法は、上記デザイナーのメタデータストアに記載カスタム属性テーブルを追加:

MetadataStore.AddAttributeTable(BuildAttributeTable());

Extensions.cs

このファイルは、IntelliSenseをチェックし、時間が含まれ実装の拡張方法GetMemberName <T>は(表現<FUNC画面の<T,オブジェクト>コンパイルで型のメンバの名前をの取得に使用されます> exprの) は:

GetMemberName拡張メソッド

アイデアがで提案した当初ジャフサイン(ポスト参照してくださいブログ彼は3.0#シンボルのC )をクリックし、改善ジャスティンエンジェル。 これは素晴らしいトリックタイプミスを避けるために、ですが、欠点は、それはSilverlightの参照とアセンブリの場合、純粋なに。NETアセンブリを取り出しています。 ここでは完全なソースです:

Extensions.cs:

  / /(c)の著作権マイクロソフト株式会社。
 / /このソースは)さんは被写体に、Microsoft Public Licenseの(のPL。
 / /詳細については、http://go.microsoft.com/fwlink/?LinkID=131993を参照してください。
 / /他のすべての権利を保有。

システムを使用して;
 NET Frameworkクラスを使用する。

 名前空間 Microsoft.Windows.Controls.Design.Common

     / / / <summary>
     セットの内部拡張メソッドこの/ / /及び提供一般的なソリューションを
     十分に小さい数/ / /ユーティリティの拡張子を専用しないように保証するもので
     / / /メソッドのクラスです。
     / / / </概要>
     内部クラスの静的拡張
    
         / / / <summary>
         / / /ヘルパーメソッドミスを避けるために検証をコンパイル時に名前を持つメンバを取得します。
         / / / </概要>
         / / / <typeparam>をname="T"> typeparamの/ <取得。含むクラス名をのメンバ
         ラムダ式を、通常のフォームのo name="expr"> / <paramの/ / => o.memberします。</パラメータの>
         / / /は、> /を返します<プロパティです。名前をの<returns>
         >> expr) パブリック静的な文字列 GetMemberName <T>は(表現<FUNC画面の<T,)>> exprをオブジェクト
        
            式の本体=((LambdaExpression)式)。ボディ。
             =体として MemberExpression memberExpressionはMemberExpressionの。
             ) 場合 )(memberExpression == nullの
            
                 memberExpression =(MemberExpression)((UnaryExpression)体)。オペランド;
            
             戻り memberExpression.Member.Name;
        
    
 

結論

このポストは機能の時間実装の設計について2008年12月リリースのSilverlight Toolkitは、とコントロール機能のためにSilverlightの時間設計のフレームワークのために実装する単純な導入しました。 あなたは実装をモデル化することができますし、独自のプロジェクトでフレームワークを再利用できます。 それがないからフレームワークはまだ非常に原始的な、メタデータの登録をサポートしているだけで、すべてのブレンドは今のところサポートしています。 私は、/拡張/ダイアログエディタ、デザイン時のデータ、デザイン時のカスタムインラインを追加するようにSilverlightをToolkitのフレームワークと設計時の機能改善になりますだけ等規範が

ポストとして、以前私が述べたデザイン時機能ツールキットでSilverlight 、経験のコントロール時間の設計が重要です非常に。 それだけでなく、経験と快く時の機能と、これらのコントロールを使用する開発者の生産性を向上させることも、より多くのアプリケーションは、ユーザーにドラッグアンドコントロールをドロップしてレイアウトを変更するようなユーザーインターフェイスをカスタマイズの柔軟性を与えるため、エンドユーザの経験を向上させる、または、単にデザイナーのように、それ以外のコントロールの設定を変更する実行時です。

共有し、楽しみなさい:

  • Print
  • email
  • RSS
  • Twitter
  • TwitThis
  • del.icio.us
  • LinkedIn
  • Technorati
  • Facebook
  • Google Bookmarks
  • Live
  • MySpace
  • QQ书签