Главная > время разработки , Silverlight > время разработки функций реализации в Silverlight Toolkit

Время разработки функций реализации в Silverlight Toolkit

Введение

Это второй после моего Silverlight Дизайн серии функций времени. Первый пост время разработки возможности в Silverlight Toolkit показал время разработки особенностей Silverlight Toolkit управления. Это сообщение объясняет, как она реализуется. Надеюсь, это сообщение может помочь объяснить нашим исходный код, демонстрирующий, как реализовать конструктивные особенности времени для Silverlight, а также предоставление базы и читатели исходные коды можно использовать непосредственно в их собственных проектах.

Обзор

Скачать "Silverlight Toolkit - Binaries, примеры, документация, модульных тестов и источники" в декабре 2008 выпуска , открытый SourceSilverlight.Controls.sln в Visual Studio, и мы увидим, что Есть 12 дизайн-проектов согласно Проекту папку решения, три для каждого элемента управления сборки.

Silverlight.Controls.sln в Visual Studio

Возьмите управления проектом, например, Есть три дизайн-проекты:

  • 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 только.

Существует также Design.Common папку, которая содержит два файла: Extensions.cs и MetadataBase.cs, которые являются общими для всех дизайн-проектов.

Настоятельно рекомендуется прочитать блог Джастин Ангела сообщение Silverlight время разработки расширения : она дает неплохое представление / обзор информации о Silverlight время разработки расширяемость, на которых ниже реализация основана.

Проект

Все 12 проектов дизайна следовать той же схеме реализации, так что я буду просто использовать Control.Design проекта, чтобы объяснить их всех.

Нагрузка Silverlight.Controls.sln в исходный каталог в Visual Studio в первый раз, мы увидим экран, как показано ниже:

Silverlight.Controls.Design.csproj в Visual Studio

  • Controls.Design есть проект зависимости от проекта Controls. Эта зависимость управления гарантирует, что проект построен первый, и Controls.Design имеет ссылку на сборку встроено Microsoft.Windows.Controls по проекту управления. Проектирования сборок время всегда ссылается на сборку во время выполнения он предоставляет возможности для проектирования.
  • Controls.Design ссылки Microsoft.Windows.Design & Microsoft.Windows.Design.Extensibility сборки, оба из которых находятся в каталоге% DevEnvDir% PublicAssemblies (C: Program FilesMicrosoft Visual Studio 9.0Common7IDEPublicAssemblies на моем ноутбуке). Проектирования сборок время часто ссылки этих двух узлов, которые обеспечивают основу расширяемости конструктора. Сборка время разработки системы всегда ссылается сборка тоже, который содержит имен System.ComponentModel, где многие из атрибутов метаданных (например, CategoryAttribute, DescriptionAttribute) определены.
  • Controls.Design ссылки System.Windows сборки. Мы видим, ссылка в Controls.Design.csproj тоже:

    <Reference Include="System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, processorArchitecture=MSIL">
    <SpecificVersion> False </ SpecificVersion>
    <HintPath> .. BinariesSystem.Windows.dll </ HintPath>
    <Private> False </ Private>
    </ Reference>

    Пожалуйста, обратите внимание:

    • 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> (Expression <Func <T, object>> выражение) метода в Extension.cs, которые мы обсудим чуть позже в этой должности. Смесь. NET и Silverlight ссылки создает все виды интересных вопросов, как мы увидим в ближайшее время.

      Ниже ILDASM скриншот показывает смешанные ссылки на NET и Silverlight сборки, Microsoft.Windows.Controls.Design.dll.:
      ILDASM Microsoft.Windows.Controls.Design.dll Microsoft.Windows.Controls.Design манифеста сборки

      • . Версии 2:0:21024:1838 является номер версии Silverlight Toolkit-релиз 2008 года декабря.
      • . Версии 3:5:0:0 это номер версии. NET Framework 3.5.
      • . Версии 2:0:0:0 является номер версии Silverlight 2.0.
    • Когда вы первый проект Controls.Design загрузить в Visual Studio, есть «System.Windows" ссылка компонент не может быть найден "предупреждение рядом с System.Windows ссылки на сборку в окне проекта, и в окне Список ошибок тоже. Это потому, что это Controls.Design NET проект вместо Silverlight, и мы не знаем, где Silverlight установлен (он находится под C:. Программы FilesMicrosoft Silverlight2.0.31005.0 на моем ноутбуке, и в C: Program Files (X86 ) Microsoft Silverlight2.0.31005.0 на моем рабочем столе). Решением было бы событие перед построением команды .. CopySystemWindows.bat, что копии System.Windows.dll от направления Silverlight установить на .. Binaries. Поэтому, как только вы создали проект, предупреждение исчезнет, ​​как мы увидим в ближайшее время.
  • В выше Визуальный скриншот Studio, есть еще один предупредительный знак рядом с файлом Microsoft.Windows.Controls.XML в проекте вдовы, когда вы загружаете Controls.Design проект в Visual Studio в первый раз. Этот файл создается путем создания зависимого проекта управления, потому что в свойствах управления проекта -> Build вкладке опцию "XML-файл документации" установлен, и путь «.. Бинар
    iesMicrosoft.Windows.Controls.XML ". Если вы строите Controls.Design проекта, предупреждение исчезнет, ​​как мы увидим в ближайшее время.
  • Controls.Design проект Metadata.cs файла и ссылки на Extension.cs и MetadataBase.cs в Design.Common папку. Все 12 дизайн-проектов имеют эти три файла. Мы обсудим их более подробно позже.

Собрать проект Controls.Design или всего решения, мы видим:

Сборка выход Silverlight.Control.sln

  • Все объекты, построенные в порядке с 0 ошибок и 0 предупреждений.
  • Предупредительных знаков рядом с System.Windows ведения и Microsoft.Windows.Controls.XML файл исчез.
  • Анализ кода процесс сборки занимает много времени, и она генерирует два предупреждения. Первый, CA0060, является еще одним вопросом смешанные. NET и Silverlight ссылки и код в Extension.cs. Вы можете избавиться от предупреждения, копируя System.dll и System.Core.dll из каталога установки Silverlight для SourceBinaries каталог и здание снова.

MetadataBase.cs

MetadataBase.cs вместе с Metadata.cs, ​​осуществлять основу для разработки регистрации метаданных время:

  • DescriptionAttributes автоматически генерируются для общественных классов управления (то есть подклассы FrameworkElement) и их общие свойства от своих "/ / / <summary>" Комментарии XML-документации в исходном коде. (Хорошо комментируя платит! :-) )
  • Чтобы скрыть контроль класс от дизайнера, добавьте строку ниже, чтобы AddAttributes метод в Metadata.cs файле проекта:
    builder.AddCallback (TypeOf (TreeViewItem), б => b.AddCustomAttributes (новые ToolboxBrowsableAttribute (ложь)));
  • Для регистрации других пользовательских атрибутов для класса элемента управления, добавьте XxxMetadata.cs файл в проект, как и ViewboxMetadata.cs обсуждаться позже.

Если вы любите рамки, вы можете использовать MetadataBase.cs и Metadata.cs прямо в свой ​​собственный проект, с учетом Microsoft Public License включен в начало всех наших исходных файлов.

MetadataBase.cs:

 / / (С) Copyright Microsoft Corporation. / / Этот источник подлежит лицензии Microsoft Public (Ms-PL). / / См. http://go.microsoft.com/fwlink/?LinkID=131993 для деталей. / / Все другие права,  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) { } } } {/ / / <summary> / / / MetadataRegistration класса. / / / </ Резюме> общественного класса MetadataRegistrationBase {/ / / <summary> / / / Build время разработки метаданных таблицы атрибутов. / / / </ Резюме> / / / <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 (строитель =! нулевой ", AddTables вызывается с нулевым параметром!"); Ассамблеи АНМ = Assembly.GetExecutingAssembly (); Еогеасп (тип т в asm.GetTypes ()) {если (t.IsSubclassOf (TypeOf (AttributeTableBuilder))) {попробуйте {AttributeTableBuilder ATB = (AttributeTableBuilder) Activator.CreateInstance (т); builder.AddTable (atb.CreateTable ());} поймать (Exception е) {Debug.Assert (ложь, строка Format (CultureInfo.InvariantCulture, "Исключение в методе AddTables. {0} ", е));}}}} / / / <summary> / / / Возвращает или задает регистр имя ресурса к файлу встроенного XML / / / </ резюме> защищен XmlResourceName строку {получить;. набора ;} / / / <summary> / / / Возвращает или задает сборку FullName для типов »сборки квалифицированных имен / / / </ резюме> защищен AssemblyFullName строку {получаем,. множества;} / / / <summary> / / / Создать описание атрибута время выполнения файла сборки XML / / / </ резюме> / / / <param name="builder"> таблице атрибут сборки строителя </ параметр> [SuppressMessage ("Microsoft.Design", "CA1031..: DoNotCatchGeneralExceptionTypes ", Обоснование =" DLL время разработки не должны потерпеть неудачу ")] частные AddDescriptions недействительными (AttributeTableBuilder строитель) {Debug.Assert (строитель = NULL,"! AddDescriptions вызывается с нулевым параметром ");.!. если (строка IsNullOrEmpty ( XmlResourceName) | | строки IsNullOrEmpty (AssemblyFullName)) {возвращение;} XDocument xdoc = XDocument.Load (новый StreamReader (Assembly.GetExecutingAssembly ().. GetManifestResourceStream (XmlResourceName))), если (xdoc == NULL) {возвращение;} Еогеасп (XElement членом xdoc.Descendants ("член")) {попробуйте {строка имя = (строка) member.Attribute ("имя"); Ьоо isType = name.StartsWith ("T", StringComparison.OrdinalIgnoreCase), если ( isType | | name.StartsWith ("P", StringComparison.OrdinalIgnoreCase)) {Int lastDot = name.Length; строка TypeName, если (isType) {TypeName = name.Substring (2);} Else {lastDot = name.LastIndexOf ('.'); TypeName = name.Substring (2, lastDot - 2);} TypeName + = AssemblyFullName; тип Т = Type.GetType (TypeName), если (Т = NULL & & & & t.IsPublic t.IsClass & &! .. t.IsSubclassOf (TypeOf (FrameworkElement))) {строка по убыванию = member.Descendants ("резюме") FirstOrDefault () Значение, по убыванию = desc.Trim ();. убыванию = строка регистрации ("", desc.Split ( новый символ [] {'', 'т', 'п'}, StringSplitOptions.RemoveEmptyEntries)), если (isType) {builder.AddCallback (T, B => b.AddCustomAttributes (новые DescriptionAttribute (по убыванию)));} еще {строка PROPNAME = name.Substring (lastDot + 1); PropertyInfo пи = t.GetProperty (PROPNAME); MethodInfo миль, а если (р = NULL & & (т = pi.GetSetMethod ()) = NULL & & mi.IsPublic! ) {builder.AddCallback (T, B => b.AddCustomAttributes (PROPNAME, новые DescriptionAttribute (по убыванию)));}}}}} поймать (Exception е) {Debug.Assert (ложь, строка Format (CultureInfo.InvariantCulture,. "Исключение в методе AddDescriptions: {0}", е));}}} / / / <summary> / / / Предоставление места для добавления пользовательских атрибутов, не создавая AttributeTableBuilder подкласс / / / </ резюме> / / /. <param name="builder"> таблице атрибут сборки строителя. </ параметр> защищенной виртуальной AddAttributes недействительными (AttributeTableBuilder строитель) {}}} 

MetadataBase.cs реализует MetadataRegistrationBase класса. Давайте рассмотрим некоторые его основные методы:

AddDescriptions

Все бегут проектов время собраний "XML-файл документации" опция включена, и путь, как ".. BinariesMicrosoft.Windows.Controls.XML", в проекте -> Свойства -> Build вкладке выходного сечения. Вы также можете найти настройки в csproj файл, как показано ниже.:

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

Ниже приводится выдержка из Microsoft.Windows.Controls.XML чтобы показать, что при генерации документации XML-файл выглядит следующим образом:

 Содержание декоратор, который может растягиваться и масштаба ни одного ребенка, чтобы заполнить имеющийся  детского элемент по умолчанию Viewbox в  > < param name ="o" > The object typed value to be checked. </ param > < returns > True if o is a valid Stretch enum value, false o/w. </ returns > </ member > < member name ="P:Microsoft.Windows.Controls.Viewbox.Child" > < summary > Gets or sets the single child element of a Viewbox. </ summary > </ member > </ members > </ doc > ли прошли в объект значение допустимым Stretch значение перечисления. </ резюме> <параметр имя = "о"> объекта типизированного значения должны быть проверены. </ параметра> <возвращает> Правда, если а является допустимым значением перечисления Stretch, ложные о / w. </ возвращает> </ пользователь> <имя члена = "P: Microsoft.Windows.Controls.Viewbox.Child">. <резюме> Получает или задает один дочерний элемент Viewbox </ резюме> < / пользователь> </ Члены> </ DOC> 

Имя атрибута каждого элемента <member> следующим схеме:

  • "T: Microsoft.Windows.Controls.Viewbox": "T:" указывает, что это типа, за которым следует полное имя типа;
  • "F: Microsoft.Windows.Controls.Viewbox.ChildElementName": "F:" указывает, что это поле, а затем поля на полное имя;
  • "М: Microsoft.Windows.Controls.Viewbox.IsValidStretchValue (System.Object)": "М:" указывает, что это метод, за которым следует полное имя метода и параметры;
  • "P: Microsoft.Windows.Controls.Viewbox.Child": "Р:" указывает, что это имущество, за которым следует полное имя свойства;

Control.Design проекте ссылки на Microsoft.Windows.Controls.XML файл в качестве внедренного ресурса:

  • Microsoft.Windows.Controls.XML как внедренный ресурс
  • Controls.Design.csproj:

     Include ="..BinariesMicrosoft.Windows.Controls.XML" /> <EmbeddedResource Include = ".. BinariesMicrosoft.Windows.Controls.XML" /> 

AddDescriptions метод анализирует встроенный XML-файл и генерирует DescriptionAttribute для общественных классов управления и их общие свойства:

  MetadataBase.cs: 134: builder.AddCallback (T, B => b.AddCustomAttributes (новые DescriptionAttribute (по убыванию)));
 MetadataBase.cs: 143: builder.AddCallback (T, B => b.AddCustomAttributes (PROPNAME, новые DescriptionAttribute (по убыванию))); 
AddAttributes

AddAttributes, как правило, переопределения в Metadata.cs файл, чтобы добавить ToolboxBrowsableAttribute (ложь) пользовательских атрибутов для управления классами, которые не должны отображаться в панели инструментов дизайнера:

  • если класс элемента управления должно быть скрыто от всех дизайнеров, добавьте ToolboxBrowsableAttribute (ложь) пользовательских атрибутов для проекта Xxx.Design;
  • если оно должно быть скрыто от Visual Studio только добавить пользовательский атрибут Xxx.VisualStudio.Design проекта;
  • если оно должно быть скрыто от Expression Blend только добавить пользовательский атрибут Xxx.Expression.Design проекта;

Ниже AddAttributes реализации в Metadata.cs проекта Controls.VisualStudio.Design:

  / / / <summary>
 / / / Предоставление места для добавления пользовательских атрибутов, не создавая AttributeTableBuilder подкласса.
 / / / </ Резюме>
 / / / <param Name="builder"> таблице атрибут сборки строителя. </ Параметр>
 защищены переопределить недействительным AddAttributes (AttributeTableBuilder строитель)
 {
     ToolboxBrowsableAttribute( false ))); builder.AddCallback (TypeOf (TreeViewItem), б => b.AddCustomAttributes (новые ToolboxBrowsableAttribute (ложь)));
 } 
AddTables

Чтобы добавить атрибуты, кроме ToolboxBrowsableAttribute (ложь) для типа, добавьте XxxMetadata.cs файлов, как ViewboxMetadata.cs ниже соответствующего проекта:

ViewboxMetadata.cs:

 / / (С) Copyright Microsoft Corporation. / / Этот источник подлежит лицензии Microsoft Public (Ms-PL). / / См. http://go.microsoft.com/fwlink/?LinkID=131993 для деталей. / / Все другие права,  ViewboxMetadata : AttributeTableBuilder { /// <summary> /// To register design time metadata for Viewbox. /// </summary> public ViewboxMetadata() : base () { AddCallback( typeof (Viewbox), b => { b.AddCustomAttributes(Extensions.GetMemberName<Viewbox>(x => x.BorderThickness), new BrowsableAttribute( false )); b.AddCustomAttributes(Extensions.GetMemberName<Viewbox>(x => x.BorderBrush), new BrowsableAttribute( false )); b.AddCustomAttributes(Extensions.GetMemberName<Viewbox>(x => x.Background), new BrowsableAttribute( false )); b.AddCustomAttributes(Extensions.GetMemberName<Viewbox>(x => x.Foreground), new BrowsableAttribute( false )); b.AddCustomAttributes(Extensions.GetMemberName<Viewbox>(x => x.Child), new CategoryAttribute(Properties.Resources.CommonProperties)); b.AddCustomAttributes(Extensions.GetMemberName<Viewbox>(x => x.Stretch), new CategoryAttribute(Properties.Resources.CommonProperties)); b.AddCustomAttributes(Extensions.GetMemberName<Viewbox>(x => x.StretchDirection), new CategoryAttribute(Properties.Resources.CommonProperties)); }); } } } {/ / / <summary> / / / Чтобы зарегистрироваться время разработки метаданных для Viewbox / / / </ резюме> внутренний класс ViewboxMetadata:.. AttributeTableBuilder {/ / / <summary> / / / Для регистрации метаданных времени разработки для Viewbox / / / </ резюме> общественный ViewboxMetadata (): базовый () {AddCallback (TypeOf (Viewbox), б => {b.AddCustomAttributes (Extensions.GetMemberName <Viewbox> (х => x.BorderThickness), новые BrowsableAttribute (ложь)) ; b.AddCustomAttributes (Extensions.GetMemberName <Viewbox> (х => x.BorderBrush), новые BrowsableAttribute (ложь)); b.AddCustomAttributes (Extensions.GetMemberName <Viewbox> (х => x.Background), новые BrowsableAttribute (ложь )); b.AddCustomAttributes (Extensions.GetMemberName <Viewbox> (х => x.Foreground), новые BrowsableAttribute (ложь)); b.AddCustomAttributes (Extensions.GetMemberName <Viewbox> (х => x.Child), новые CategoryAttribute (Properties.Resources.CommonProperties)); b.AddCustomAttributes (Extensions.GetMemberName <Viewbox> (х => x.Stretch), новые CategoryAttribute (Properties.Resources.CommonProperties)); b.AddCustomAttributes (Extensions.GetMemberName <Viewbox> ( х => x.StretchDirection), новые CategoryAttribute (Properties.Resources.CommonProperties));});}}} 
  • Рекомендуется следовать именования здесь. Возьмите Viewbox например, имя файла ViewboxMetadata.cs, ​​и имя класса ViewboxMetadata.
  • Метаданных класс должен наследоваться от AttributeTableBuilder.
  • Вы можете добавлять пользовательские атрибуты в конструкторе класса метаданных:
    • Можно использовать как модель обратного вызова (как в ViewboxMetada.cs выше) или прямой модели. Модели обратного вызова, предположительно, более эффективным.
      • прямой пример модели:

        AddCustomAttributes (

        TypeOf (Viewbox), / / ​​тип

        "BorderThickness", / / ​​имя свойства

        Новый атрибут [] {нового BrowsableAttribute (ложь)}); / / пользовательский массив атрибутов

    • Для обеспечения параметра имя свойства AddCustomAttribute звонок, вы можете использовать метод Extensions.GetMemberName (), как в ViewboxMetadata.cs (обсудим это позже в должность), чтобы получить имя свойства в тип безопасным способом, или предоставить имя свойства непосредственно как строки типа "BorderThickness" в выше прямой реализации модели.

AddTables (AttributeTableBuilder строитель) метода:

  • перечисляет все подклассы AttributeTableBuilder в выполнении сборки
  • создает экземпляр каждого найденного AttributeTableBuilder подкласса:

    AttributeTableBuilder ATB = (AttributeTableBuilder) Activator.CreateInstance (т);

  • добавить атрибут таблицы найден класс для производителей оборудования:

    builder.AddTable (atb.CreateTable ());

Metadata.cs

Metadata.cs реализует MetadataRegistration класс, который наследует от класса MetadataRegistrationBase реализованы в MetadataBase.cs. Он также реализует IRegisterMetadata интерфейс.

Metadata.cs:

 / / (С) Copyright Microsoft Corporation. / / Этот источник подлежит лицензии Microsoft Public (Ms-PL). / / См. http://go.microsoft.com/fwlink/?LinkID=131993 для деталей. / / Все другие права,  MetadataRegistration : MetadataRegistrationBase, IRegisterMetadata { /// <summary> /// Design time metadata registration class. /// </summary> public MetadataRegistration() : base () { AssemblyName asmName = typeof (Viewbox).Assembly.GetName(); XmlResourceName = asmName.Name + ".Design." + asmName.Name + ".XML" ; // "Microsoft.Windows.Controls.Design.Microsoft.Windows.Controls.XML" AssemblyFullName = ", " + asmName.FullName; } /// <summary> /// Borrowed from System.Windows.Controls.Toolbox.Design.MetadataRegistration: /// use a static flag to ensure metadata is registered only one. /// </summary> private static bool _initialized; /// <summary> /// Called by tools to register design time metadata. /// </summary> public void Register() { if (!_initialized) { MetadataStore.AddAttributeTable(BuildAttributeTable()); _initialized = true ; } } /// <summary> /// Provide a place to add custom attributes without creating a AttributeTableBuilder subclass. /// </summary> /// <param name="builder">The assembly attribute table builder.</param> protected override void AddAttributes(AttributeTableBuilder builder) { } } } {/ / / <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: / / / использование статического флаг для обеспечения метаданных зарегистрирован только один / / / </ резюме> частных статических Ьоо _initialized,.. / / / <summary> / / / Вызывается инструменты для регистрации метаданных времени разработки / / / </ резюме> общественный Регистрация недействительными () {если {MetadataStore.AddAttributeTable (BuildAttributeTable ()) (_initialized!); _initialized = true;}} / / / <summary> / / / Предоставление места для добавления пользовательских атрибутов, не создавая AttributeTableBuilder подкласс / /. / </ резюме> / / / <param name="builder"> таблице атрибут сборки строителя. </ параметр> защищены переопределить недействительным AddAttributes (AttributeTableBuilder строитель) {}}} 

Давайте обсудим некоторые из ее основных методов:

MetadataRegistration

Этот конструктор инициализирует два ключевых областях:

  • XmlResourceName: имя ресурса вложенного файла документации XML, используемый метод MetadataRegistrationBase.AddDescriptions.
  • AssemblyFullName: полное имя сборки, время выполнения этой сборке время разработки для.

Нужно заменить тип Viewbox с вашим собственным классом, если вы используете Metadata.cs в ваш собственный дизайн проекта.

Реестр

Это единственный метод IRegisterMetadata интерфейс. Он добавляет, пользовательские таблицы атрибутов, построенный из AddDescripions, AddAttributes & AddTables методы, описанные выше, хранилище метаданных дизайнера:

MetadataStore.AddAttributeTable (BuildAttributeTable ());

Extensions.cs

Этот файл содержит реализацию метода расширения GetMemberName <T> (Expression <Func <T, object>> выражение), который используется для получения имени члена типа с компиляции проверять время и IntelliSense:

GetMemberName метод расширения

Идея была изначально предложенный Джафар Хусейн (см. его сообщение в блоге символы в C # 3.0 ), а затем улучшить, Джастин Ангел . Это большая уловка, чтобы избежать опечаток, но недостатком является то, что он тянет в ссылках и Silverlight сборки в противном случае чистой. NET сборки. Вот полный источник:

Extensions.cs:

  / / (С) Copyright Microsoft Corporation.
 / / Этот источник подлежит лицензии Microsoft Public (Ms-PL).
 / / См. http://go.microsoft.com/fwlink/?LinkID=131993 для деталей.
 / / Все другие права защищены.

 использования системы;
 использованием System.Linq.Expressions;

 Пространство имен Microsoft.Windows.Controls.Design.Common
 {
     / / / <summary>
     / / / Это набор внутренних методов расширения обеспечивают общие решения и
     / / / Коммунальные услуги в достаточно малой номер не гарантирует посвященный расширению
     / / / Методы класса.
     / / / </ Резюме>
     внутренние статические расширения класса
     {
         / / / <summary>
         / / / Вспомогательный метод для получения имени члена компиляции время проверки, чтобы избежать опечатки.
         / / / </ Резюме>
         / / / <typeparam Name="T"> содержащих класс члена, фамилия которого получены. </ Typeparam>
         / / / <param Name="expr"> лямбда-выражения, как правило, в виде о => o.member. </ Параметр>
         / / / <returns> Имя свойства. </ Возвращает>
         >> expr) общественности статической строки GetMemberName <T> (Expression <Func <T, объекта>> выражение)
         {
             . Выражение тела = ((LambdaExpression) выражение) органа;
             MemberExpression MemberExpression = тело как MemberExpression;
             ) если (MemberExpression == NULL)
             {
                 MemberExpression = (MemberExpression) ((UnaryExpression) органа) операнда.
             }
             возвращение memberExpression.Member.Name;
         }
     }
 } 

Заключение

Этот пост описано реализации конструктивных особенностей времени в декабре 2008 релиз из Silverlight Toolkit и представила простой рамки для осуществления функций проектирования для элементов управления Silverlight. Вы можете моделировать реализации и повторного использования базы в собственных проектах. Рамках все еще очень примитивны, вспомогательные метаданные только регистрация, так как это все, что смесь поддерживает на данный момент. Я буду смотреть в улучшении основы и особенности проектирования для Silverlight Toolkit, как и добавление пользовательских встроенный / распространила / диалог редакторов, данные проектирования, только во время разработки поведения и т.д.

Как я уже говорил в предыдущем посте время разработки возможности в Silverlight Toolkit , время разработки, помогая решать задачи управления очень важно. Она не только улучшает опыт и производительность труда разработчиков, которые используют эти элементы управления с функциями, соизволил времени, но и улучшает опыта конечных пользователей, поскольку все больше и больше приложений предоставить пользователям большую гибкость в настройке пользовательского интерфейса, такие как изменение макета, перетаскивания элементов управления , или изменение настроек управления, так же, как в конструкторе, за исключением его во время выполнения.

  1. 21 апреля 2009 в 08:19 | # 1

    @ FIDER
    Для отладки, попробуйте следующее:
    * Убедитесь, что наименование и местоположение вашего управления и проектирования сборки верны, то есть, если ваш контроль сборки foo.dll в C: \ TMP, то дизайн сборка foo.design.dll в C: \ TMP или с: \ TMP \ Design.
    * Открыть свой дизайн-проект, установить точки останова в вашем Регистрация функцию и установить цель отладки вашего имущества проекта для запуска Visual Studio
    * Нажать F5, новый экземпляр VS запущена, создать новый проект, SL, затем пройти через Выбрать элементы диалога, Tab выберите Silverlight, перейдите в папку C: \ TMP и выберите свой контроль DLL foo.dll.
    * Ваш останова должен попасть.

    Еще одной распространенной причиной проблем: убедитесь, что он типа Silverlight (TreeViewItemAdv в вашем примере) вы указываете метаданные.

    Надеюсь, что это помогает!

    Спасибо,

    -Ning

  2. FIDER
    21 апреля 2009 в 3:18 | # 2

    Привет Нин,

    Я создал, как узлы и помещены в локальную папку и GAC. Я пытаюсь открыть сборки из локальной папки в диалоговом выбирать предметы - Silverlight Компоненты вкладки. Его выбирает все классы в сборках и добавляются в панели инструментов.

    Так дайте мне знать, как мне отладки этих проектов

    С уважением,
    FIDER

  3. FIDER
    20 апреля 2009 в 04:04 | # 3

    Привет Нин,

    Хорошие статьи. Я создал дизайн и visualstudio.design проект для моего управления Silverlight обычай. Моя цель состоит только скрыть класса из панели инструментов. Я metadata.cs файл, в котором в Я поставил ToolboxBrowsableAttribute к ложным для классов, которые должны быть hidded. Мой metadata.cs файл выглядит следующим образом.

    Метаданные общественных класса: IRegisterMetadata
    {

    Регистрация общественных недействительными ()
    {
    AttributeTableBuilder строитель = новый AttributeTableBuilder ();
    builder.AddCallback (TypeOf (TreeViewItemAdv), б => b.AddCustomAttributes (новые ToolboxBrowsableAttribute (ложь)));
    MetadataStore.AddAttributeTable (builder.CreateTable ());
    }
    }

    Но я все еще мог получить класс не отображается.

    Любая помощь будет заметна.

    С уважением,

    FIDER.

    • 20 апреля 2009 в 14:52 | # 4

      Привет FIDER,

      Ваш код выглядит правильно. Мое предложение, чтобы пройти, чтобы подтвердить свой код загружается и выполняется правильно:
      * Установка точки останова в вашем Регистрация функцию и посмотреть, является ли это хит. VS2010 и Blend3 использовать новые MWD и другую точку входа (IProvideAttributeTable.AttributeTable вместо IRegisterMetadata.Register), и если имя или расположение вашего проекта DLL-то не так по отношению к соответствующей библиотеке DLL времени выполнения, ваш дизайн DLL не будет погруженных либо. Это частая причина проблем.
      * Если ваш точки останова, пошаговое выполнение кода, а затем проверить эффект, через AttributeTable.ValidateTable, AttributeTable.GetCustomAttributes или TypeDescriptor.GetAttributes т.д.

      Надеюсь, что это помогает.

      Спасибо,

      -Ning

  1. 21 января 2009 в 18:31 | # 1
  2. 24 января 2009 в 20:24 | # 2
  3. 31 марта 2009 в 02:16 | # 3
  4. 3 апреля 2009 в 11:48 | # 4
  5. 22 апреля 2009 в 23:17 | # 5
  6. 11 мая 2009 в 13:14 | # 6