存档

帖子标记'控制'

编辑Silverlight控件模型和默认初始化

11日,2009年 4评论

介绍

这是一系列的设计时功能的实现Silverlight工具包的一部分。 这篇文章使用图表默认初始化,来说明如何实现Silverlight控件的默认初始化和解释底层编辑模型架构。

经验

如果您安装2009年3月发布 的Silverlight 3工具包 ,您可以拖动图表控件从混合资产库和它拖放到设计器图面,和你有很好的初始化和呈现的图表:

Chart default initializer

你可以阅读更多关于它在以前的职位Silverlight工具包设计的时代特点:2009年3月版本更新

建筑

DefaultInitializer

它实际上是非常简单的Silverlight控件提供一个默认的初始化:

下面的截图显示了执行DefaultInitializer抽象基类和其他类不久将讨论Microsoft.Windows.Design.Model命名空间:

DefaultInitializer

初始化完成InitializeDefaults覆盖,结果XAML序列。 因此,第一步是在实现一个默认的初始到生产所需的XAML定义。

编辑模型

一旦结果XAML定义,我希望有一个更高层次的抽象/方法,只是采取的XAML。 但不幸的是,我们必须使用低得多的水平(从而更灵活和强大)势在必行API调用编辑模式,如类组成的ModelItemModelPropertyModelEventModelFactoryModelService MSDN页面编辑的建筑模型,给出了一个基本的概述:

您的设计时间实现交互运行时间控制,虽然编程接口称为编辑模型。 正在设计中的对象被称为可编辑对象。

您的控件在可扩展应用程序标记语言(XAML)定义。 更新您的控件的XAML编程所使用的编辑模式。

型号,包装,查看

编辑模型由三个功能亚基:一个模型,公众的包装,抽象模型,并表示模型的用户界面(UI),一种观点认为。 模型和视图是分开的,但包装和模型有密切的关系。 下图显示了三个亚基之间的关系。

型号的ModelItem,和视图关系

设计环境中使用的ModelItem类型通信的底层模型。 所有的变化作出的ModelItem包装,从而影响底层模型。 这使得简单的模型。 的ModelItem包装处理复杂的设计器功能,如事务支持,撤消跟踪和更改通知。

下面的类图可能有助于解释的编辑模式中的核心类之间的相互作用:

Editing Model Class Diagram

下面的XAML使用作为一个例子:

  <UserControl
     XMLNS =“http://schemas.microsoft.com/winfx/2006/xaml/presentation”
     的xmlns:X =“http://schemas.microsoft.com/winfx/2006/xaml”
     Width ="640" Height ="480" > X:CLASS =“ModelTest.Page”WIDTH =“640”HEIGHT =“480”>
     x:Name ="LayoutRoot" Background ="White" > < 电网 :名称 =“LayoutRoot的” 背景 “白”>
         x:Name ="Button" > <X 按钮 :名称 =“按钮”>
             x:Name ="Rectangle" /> < 矩形 :名称 =“矩形”/>
         > </ 按钮 >
     > </  >
 > </ UserControl的 > 

  • 的ModelItem:假设变是上面的按钮控制的ModelItem
    • 名称为x:Name属性在XAML中:item.Name =“按钮”坚持在XAML中的x:名称=“按钮”。
    • ItemType的是底层控制的对象类型,并决定在XAML中使用的标签:item.PropertyType == tyepof(按钮),XAML标记是<Button />。
    • 属性是包裹在ModelProperty类型的属性,底层的控制,收集。 例如: 项目[“ClickMode”] = ClickMode.Release将在XAML中坚持为ClickMode =“释放”。
    • 内容代表的内容属性的ContentControl(和它的子类继承)定义:item.Content是代表Rectangle对象的ModelItem。
    • 来源:时的ModelItem代表元素是另一个元素的属性,源是该财产的ModelProperty包装。 例如,item.Content.Value.Source == item.Content / /矩形
    • 事件表示ModelEvent型包裹的底层控制的事件,收集。 从我的调试经验,它始终是空的,因此它似乎活动属性尚未由Blend3 Silverlight3尚未支持。
    • 父母是底层控制逻辑父,包裹的ModelItem类型。 前,:item.Parent是电网的ModelItem。
    • 根是根视觉,前的ModelItem包装:,item.Root代表的UserControl。
  • ModelProperty:假设变量支柱的 Button.Content,即道具= item.Content ModelProperty,
    • 名称是底层控制的财产的名称。 它坚持在XAML中的属性名称。 例如:prop.Name ==“内容”。
    • PropertyType是底层控制这个ModelProperty对象代表的财产的Type对象。 例如:prop.PropertyType = typeof运算(对象)。
    • AttachedOwnerType是类型对象的控制,首先定义属性此ModelProperty对象代表。 例如:prop.AttachedOwnerType == typeof运算(ContentControl中)/ /注:不扣。
    • 值是包裹的ModelItem类型,底层控制的财产价值。 例如:prop.Value是代表Rectangle对象的ModelItem。
    • 家长控制,包裹的ModelItem类型,该财产属于。 例如:prop.Parent ==项目
  • ModelEvent:如上所述,item.Events是总是空的,所以它似乎并不支持Silverlight3尚未,ModelEvent是在Blend3。 但假设它的工作原理,变量的EVT就是Button.Click,即ModelEvent,EVT = item.Events [“点击”,
    • 名称是事件的名称。 例如:evt.Name ==“点击”。
    • 事件类型是事件委托的类型,如:evt.EventType == typeof运算(RoutedEventHandler)。
    • 处理程序的事件处理程序的字符串集合,前:evt.Handlers的=新的字符串[] {“Button_Click”}将持续点击=“Button_Click”。 注:这是纯粹的猜测,因为目前还不支持ModelEvent,我不知道是否/何时/如何将Silverlight的支持。
    • 家长控制,包裹的ModelItem类型,该事件属于。 例如:evt.Parent ==项目

实施

图表默认初始化类ChartDefaultInitializer在ChartDefaultInitializer.cs实施的,并登记在ChartMetadata.cs。 这两个文件是在Silverlight.Controls.Design.sln Controls.DataVisualization.Toolkit.Design.csproj。 请之前读取更多的信息后在Silverlight工具包的设计时功能的实现

导致的XAML

作为第一步,定义结果XAML将ChartDefaultInitializer生产的:

  Title ="Chart Title" > < 图表:图表 标题 =“图表标题”>
     > < 图表:Chart.DataContext>
         > <PointCollection>
             X ="1" Y ="10" /> <  X =“1”:Y =“10”/>
             X ="2" Y ="20" /> <  X =“2”:Y =“20”/>
             X ="3" Y ="30" /> <  X =“3”:Y =“30”/>
             X ="4" Y ="40" /> <  X =“4”:Y =“40”/>
         > </ PointCollection>
         > < 图表:Chart.Series>
             ItemsSource ="{Binding}" < 图表:ColumnSeries 的ItemsSource =“{绑定}”
                 DependentValuePath 的“X”
                 IndependentValuePath =“Y”,/>
         > </ 图表:Chart.Series>
     > </ 制图:Chart.DataContext>
 > </ 图表:图表 > 

注册

完成下面的代码ChartMetadata.cs:

  (ChartDefaultInitializer))); b.AddCustomAttributes( 新FeatureAttribute(typeof运算 (ChartDefaultInitializer))); 

参考文献

见下面的截图:

References

即使的DefaultInitializer是在3.5版本的Microsoft.Windows.Design.Interaction.dll(在%devenvdir%的\ PublicAssemblies,即C:\ Program Files文件\微软Visual Studio 9.0 \ Common7 \ IDE \ 32位Windows PublicAssemblies),它是不支持Blend2或Visual Studio 2008 Silverlight的。 据由Blend3和Visual Studio 2010的支持,但他们同时切换到新版本Microsoft.Windows.Design *。DLL(Blend 3的预览3.7,8.0 Blend 3的RTM和Visual Studio 2010),所以我们需要链接较新版本的MWDs。 请参阅之前发表如何撰写Silverlight设计时的所有设计师:Visual Studio 2008中,混合2 Blend 3中,Visual Studio 2010的更多信息。

还请注意参考Silverlight的System.Windows.dll中的别名,的PointCollection是专门的Silverlight,WPF的。 由于WPF和Silverlight共享很多相同的命名空间中的类, 它是重要的Silverlight类型,而不是WPF的,用来创建Silverlight控件的默认初始化的ModelItem和ModelProperty。

集合

请注意在下面的截图,而可以通过ModelProperty.SetValue设置的所有其他财产的价值:

ChartDefaultInitializer

Chart.Series是集合类型(收集<Series>),所以它的价值,必须首先创造的ModelItem值通过ModelFactory.CreateItem的,然后添加通过ModelProperty.Collection.Add创建的ModelItem。 否则,即使可能会产生正确的XAML,Blend会不会刷新正确呈现图表控件,你必须重新载入页面,有它正确呈现。

ChartDefaultInitializer.cs

  / /版权所有(C)Microsoft Corporation版权所有。
 / /这个源是受微软公共许可协议(MS-PL)。
 / /详细信息,请参阅http://go.microsoft.com/fwlink/?LinkID=131993。
 / /保留所有其他权利。

 extern别名的Silverlight;
 使用 System.Windows.Controls.DataVisualization.Charting;
 使用 System.Windows.Controls.Design.Common;
 使用 Microsoft.Windows.Design.Metadata;
 使用 Microsoft.Windows.Design.Model;
 使用偏南=的Silverlight :: System.Windows;
 使用 SSWD = Silverlight的:: System.Windows.Data;
 使用 SSWM = Silverlight的:: System.Windows.Media;

 命名空间 System.Windows.Controls.DataVisualization.Design
 {
     / / / <summary>
     / / /默认初始化图表。
     / / / </摘要>
     内部类 ChartDefaultInitializer:DefaultInitializer
     {
         / / / <summary>
         / / /设置图表的默认属性值。
         / / / </摘要>
         / / / <param name="item">走势的ModelItem。</ PARAM>
         公众覆盖的无效 InitializeDefaults(的ModelItem项目)
         {
             字符串的propertyName;

             / / <Charting:Chart的Title="Chart Title">
             propertyName的= Extensions.GetMemberName <Chart>(X => x.Title);
             item.Properties [propertyName的]的SetValue(Properties.Resources.ChartTitle);

             / / <Charting:Chart.DataContext>
             / / <PointCollection>
             / / <point的X="1" Y="10"
             / / <point的X="2" Y="20"
             / / <point的X="3" Y="30"
             / / <point的X="4" Y="40"
             / / </ PointCollection>
             / / </制图:Chart.DataContext>

             SSWM :: PointCollection defaultItemsSource =  SSWM :: PointCollection();
             i = 1; i <= 4; i++) (I = 1;我<= 4; I + +)
             {
                 defaultItemsSource.Add( 偏南::点(I,10 * I));
             }

            添加= propertyName的Extensions.GetMemberName <Chart>(X => x.DataContext);
             item.Properties [propertyName的]的SetValue(defaultItemsSource);

             / / <Charting:Chart.Series>
             / / <图表:ColumnSeries的ItemsSource =“{绑定}”
             / / DependentValuePath =“X”,
             / / IndependentValuePath的=“Y”,/>
             / / </图表:Chart.Series>

            的ModelItem columnSeries ModelFactory.CreateItem(item.Context,typeof运算 (ColumnSeries));
            添加= propertyName的Extensions.GetMemberName <ColumnSeries>(X => x.ItemsSource);
            
             propertyName的= Extensions.GetMemberName <ColumnSeries>(X => x.DependentValuePath);
             columnSeries.Properties [propertyName的]的SetValue(“X”号 );
             propertyName的= Extensions.GetMemberName <ColumnSeries>(X => x.IndependentValuePath);
             columnSeries.Properties [propertyName的]的SetValue(“Y”字 );

             propertyName的= Extensions.GetMemberName <Chart>(X => x.Series“);
             item.Properties [propertyName的Collection.Add(columnSeries);
         }
     }
 } 

technorati