Modification d'initialisation Modèle & défaut pour les contrôles Silverlight
Présentation
Cela fait partie de la série sur la mise en œuvre caractéristique de conception du temps dans Silverlight Toolkit . Ce message utilise l'initialiseur défaut graphique pour illustrer comment mettre en œuvre initialiseur par défaut des contrôles Silverlight, et d'expliquer l'architecture sous-jacente du modèle d'édition.
Expérience
Si vous installez Silverlight Toolkit 3 en Mars 2009 Communiqué , vous pouvez faire glisser le contrôle Chart de Bibliothèque Asset Blend et déposez-le sur la surface de concepteur, et vous avez un tableau bien initialisées et rendu:
Vous pouvez lire plus à ce sujet dans antérieure après Caractéristiques Silverlight Toolkit Design Time: Mise à jour Mars 2009 Release .
Architecture
DefaultInitializer
Il est en fait assez simple de fournir un initialiseur par défaut pour un contrôle Silverlight:
- mettre en œuvre une sous-classe de DefaultInitializer , et substituer sa InitializeDefaults fonction
- associer la classe initialiseur par défaut avec la classe de contrôle via un FeatureAttribute
Ci-dessous copie d'écran montre la mise en œuvre de la classe de base abstraite DefaultInitializer, et d'autres classes dans le namespace Microsoft.Windows.Design.Model qui sera discuté prochainement:
L'initialisation est fait en priorité InitializeDefaults, et le résultat est sérialisé dans XAML. Donc la première étape dans la mise en œuvre d'un initialiseur de défaut est de définir le XAML désiré d'être produite.
Modification de Modèle
Une fois le résultat XAML est définie, je souhaite qu'il y est une méthode de niveau supérieur d'abstraction / cela ne ferait que prendre le XAML. Mais malheureusement, nous devons utiliser un niveau beaucoup plus faible (donc plus souple et plus puissant) API impératif appelé édition modèle qui se compose de classes, comme ModelItem , ModelProperty , ModelEvent , ModelFactory et ModelService . La page MSDN Modèle d'architecture d'édition donne un aperçu de base:
Votre conception de la mise en œuvre en temps interagit avec run-time contrôle via une interface de programmation appelé le modèle d'édition. Les objets en cours de conception sont appelés des objets modifiables.
Vos contrôles sont définis dans Extensible Application Markup Language (XAML). Vous mettez à jour le code XAML pour vos contrôles par programmation en utilisant le modèle d'édition.
Modèle, Wrapper, et de
Le modèle d'édition se compose de trois sous-unités fonctionnelles: un modèle, une enveloppe publique que les résumés du modèle, et une vue qui représente l'interface utilisateur (UI) du modèle. Le modèle et la vue sont distinctes, mais la cape et le modèle sont étroitement liées. L'illustration suivante montre la relation entre les trois sous-unités.
L'environnement de conception utilise les ModelItem Type de communiquer avec le modèle sous-jacent. Toutes les modifications sont apportées à l' ModelItem wrappers, qui affectent le modèle sous-jacent. Cela permet au modèle d'être simple. Le ModelItem emballages gérer caractéristiques concepteur complexes, tels que le support des transactions, défaire le suivi et les notifications de changement.
Voici le diagramme de classes peut aider à expliquer les interactions entre les classes de base du modèle d'édition:
Utilisez-dessous XAML comme un exemple:
- ModelItem: supposons élément variable est le ModelItem pour le contrôle Button ci-dessus,
- Le nom est persisté comme x: Name attribut en XAML: item.Name = "Bouton" est conservé dans XAML en tant que x: Name = "Bouton".
- ItemType est l'objet Type du contrôle sous-jacent, et décide de l'étiquette utilisée en XAML: item.PropertyType == tyepof (Button), et la balise XAML est <Button />.
- Propriétés de la collection de propriétés, enveloppé dans le type ModelProperty, du contrôle sous-jacent. Par exemple: item ["ClickMode"] = ClickMode.Release sera persisté dans XAML en tant que ClickMode = "Release".
- Contenu représente la propriété de contenu définis dans ContentControl (et hérité par ses sous-classes): item.Content est le représentant ModelItem l'objet Rectangle.
- Source: quand un ModelItem représente un élément qui a une propriété d'un autre élément, la source est le wrapper ModelProperty de cette propriété. Par exemple, item.Content.Value.Source == item.Content / / Rectangle.
- Événements représente la collecte des événements de contrôle sous-jacent, enveloppé dans le type ModelEvent. De par mon expérience de débogage, il est toujours nul, il semble donc propriété Events n'est pas encore supporté par Blend3 pour Silverlight3 encore.
- Parent est le parent logique du contrôle sous-jacent de l', enveloppé dans le type ModelItem. ex: Item.Parent est le ModelItem pour le Grid.
- Root est le wrapper ModelItem pour root visuel, ex: item.Root représente le UserControl.
- ModelProperty: supposons prop variable est la ModelProperty pour Button.Content, prop-dire item.Content =,
- Nom est le nom de la propriété du contrôle sous-jacent. Il est conservé dans XAML en tant que nom d'attribut. ex: prop.Name == "Contenu".
- PropertyType est l'objet de type de la propriété du contrôle qui sous-tendent cet objet ModelProperty représente. ex: prop.PropertyType = typeof (objet).
- AttachedOwnerType est l'objet Type du contrôle qui définit d'abord la propriété de cet objet ModelProperty représente. ex: prop.AttachedOwnerType == typeof (ContentControl) / / note: pas de bouton.
- La valeur est la valeur de la propriété du contrôle sous-jacent, enveloppé dans le type ModelItem. ex: prop.Value est le représentant ModelItem l'objet Rectangle.
- Parent est le contrôle, enveloppé dans le type ModelItem, dont la propriété appartient. ex: prop.Parent == élément.
- ModelEvent: comme mentionné ci-dessus, item.Events est toujours nul, donc il ne semble pas que ModelEvent est pris en charge pour les Blend3 Silverlight3 encore. Mais supposons qu'il fonctionne, et evt variable est la ModelEvent pour Button.Click, c'est à dire, evt = item.Events ["Click"],
- Nom est le nom de l'événement. ex: evt.Name == "Cliquer".
- EventType est le type du délégué événement, ex: evt.EventType == typeof (RoutedEventHandler).
- Gestionnaires est la collection de chaînes de gestionnaires d'événements, ex: evt.Handlers = new String [] {"Button_Click"} sera persisté que Click = "Button_Click". Note: ceci n'est que pure spéculation, car ModelEvent n'est pas encore supporté, et je ne sais pas si / quand / comment il sera pris en charge pour Silverlight.
- Parent est le contrôle, enveloppé dans le type ModelItem, dont cet événement appartient. ex: evt.Parent == élément.
La mise en œuvre
La valeur par défaut de classe initialiseur Chart ChartDefaultInitializer est mis en œuvre ChartDefaultInitializer.cs, et enregistrés dans ChartMetadata.cs. Les deux fichiers sont dans des Controls.DataVisualization.Toolkit.Design.csproj Silverlight.Controls.Design.sln. S'il vous plaît lire avant après présentent un design le temps d'implémentation dans Silverlight Toolkit pour plus d'informations.
Résultat XAML
Comme première étape, définir le résultat à produire par ChartDefaultInitializer XAML:
Title ="Chart Title" > <Tracer: Titre du graphique = "Titre du graphique"> > <Tracer: Chart.DataContext> > <PointCollection> X ="1" Y ="10" /> <Point de X = "1" Y = "10" /> X ="2" Y ="20" /> <Point de X = "2" Y = "20" /> X ="3" Y ="30" /> <Point de X = "3" Y = "30" /> X ="4" Y ="40" /> <Point de X = "4" Y = "40" /> > </ PointCollection> > <Tracer: Chart.Series> ItemsSource ="{Binding}" <Tracer: ColumnSeries ItemsSource = "{Binding}" DependentValuePath = "X" IndependentValuePath = "Y" /> > </ Charting: Chart.Series> > </ Charting: Chart.DataContext> > </ Charting:> Graphique
Inscription
Fait à ChartMetadata.cs avec le code suivant:
(ChartDefaultInitializer))); b.AddCustomAttributes (FeatureAttribute nouvelles (typeof (ChartDefaultInitializer)));
Références
Voir ci-dessous capture d'écran:
Même si DefaultInitializer est défini dans la version 3.5 du Microsoft.Windows.Design.Interaction.dll (sous DevEnvDir%% \ PublicAssemblies, par exemple c: \ Program Files \ Microsoft Visual Studio 9.0 \ Common7 \ IDE \ PublicAssemblies sur Windows 32 bits), il est pas pris en charge par les Blend2 ou Visual Studio 2008 pour Silverlight. Il est soutenu par Blend3 et Visual Studio 2010, mais ils ont tous deux passer à version plus récente d'Microsoft.Windows.Design *. dll (3,7 pour Blend 3 Preview, 4,0 pour Blend 3 RTM et Visual Studio 2010), nous avons donc besoin de relier l'encontre la nouvelle version de MWDs. S'il vous plaît voir le message avant de How to Write Design Time Silverlight pour tous les concepteurs: Visual Studio 2008, Blend 2, Blend 3, et Visual Studio 2010 pour plus d'informations.
S'il vous plaît aussi remarquer que la référence à System.Windows.dll Silverlight est un alias, et le PointCollection est spécifiquement appelé à être le Silverlight, pas de WPF. Depuis part WPF et Silverlight beaucoup de classes dans les mêmes espaces de noms, il est important que les types de Silverlight, WPF ne sont utilisées dans la création et la ModelItem ModelProperty dans initialiseur par défaut pour les contrôles Silverlight.
Collections
S'il vous plaît noter ci-dessous capture d'écran que si tous les autres biens de valeur peut être réglée via ModelProperty.SetValue:
Chart.Series est de type collection (Collection <Series>), donc sa valeur doit être réglé en créant d'abord une ModelItem via ModelFactory.CreateItem pour la valeur, puis ajoutez le ModelItem créés via ModelProperty.Collection.Add. Sinon, même si le bon code XAML peut être généré, mélange ne sera pas de rafraîchissement à rendre le contrôle de la carte correctement, vous devez recharger la page pour avoir rendu correctement.
ChartDefaultInitializer.cs
alias / / (C) Copyright Microsoft Corporation. / / Cette source est soumis à la licence Microsoft Public (Ms-PL). / / S'il vous plaît voir http://go.microsoft.com/fwlink/?LinkID=131993 pour plus de détails. / / Tous les autres droits réservés. extern alias SSWM = Silverlight::System.Windows.Media; namespace System.Windows.Controls.DataVisualization.Design { /// <summary> /// Default initializer for chart. /// </summary> internal class ChartDefaultInitializer : DefaultInitializer { /// <summary> /// Sets the default property values for chart. /// </summary> /// <param name="item">Chart ModelItem.</param> public override void InitializeDefaults(ModelItem item) { string 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> // </Charting:Chart.DataContext> SSWM::PointCollection defaultItemsSource = new SSWM::PointCollection(); for ( int i = 1; i <= 4; i++) { defaultItemsSource.Add( new SSW::Point(i, 10 * i)); } propertyName = Extensions.GetMemberName<Chart>(x => x.DataContext); item.Properties[propertyName].SetValue(defaultItemsSource); // <Charting:Chart.Series> // <Charting:ColumnSeries ItemsSource="{Binding}" // DependentValuePath="X" // IndependentValuePath="Y" /> // </Charting:Chart.Series> ModelItem columnSeries = ModelFactory.CreateItem(item.Context, typeof (ColumnSeries)); propertyName = Extensions.GetMemberName<ColumnSeries>(x => x.ItemsSource); = Silverlight:: System.Windows; utilisant SSWD = Silverlight:: System.Windows.Data; utilisant SSWM = Silverlight:: System.Windows.Media; namespace System.Windows.Controls.DataVisualization.Design {/ / / <summary> / / / Par défaut initialiseur pour le tableau / / / </ summary> ChartDefaultInitializer classe interne:.. DefaultInitializer {/ / / <summary> / / / Définit les valeurs de propriété par défaut pour le tableau / / / </ summary> / / / <param name = "item"> Graphique ModelItem </ param> public override void InitializeDefaults (point ModelItem) {propertyName chaîne;. / / <Charting:Chart Title="Chart Title"> propertyName = Extensions.GetMemberName <Chart> (x => x . Titre); 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> / / </ Charting: Chart.DataContext> SSWM:: PointCollection defaultItemsSource = new SSWM:: PointCollection (); for (int i = 1; i <= 4; i + +) {defaultItemsSource.Add (nouveau SSW: : Le point (i, 10 * i));} propertyName = Extensions.GetMemberName <Chart> (x => x.DataContext); item.Properties [propertyName] SetValue (defaultItemsSource); / / <Charting:Chart.Series>. / / <Charting:ColumnSeries ItemsSource="{Binding}" // DependentValuePath="X" // IndependentValuePath="Y" /> / / </ Charting: Chart.Series> ColumnSeries ModelItem = ModelFactory.CreateItem (item.Context, typeof (ColumnSeries)); propertyName = Extensions.GetMemberName <ColumnSeries> (x => x.ItemsSource); ); propertyName = Extensions.GetMemberName<Chart>(x => x.Series); item.Properties[propertyName].Collection.Add(columnSeries); } } } propertyName = Extensions.GetMemberName <ColumnSeries> (x => x.DependentValuePath); columnSeries.Properties [propertyName] SetValue ("X");. propertyName = Extensions.GetMemberName <ColumnSeries> (x => x.IndependentValuePath); ColumnSeries. . Propriétés [propertyName] SetValue ("Y"); propertyName = Extensions.GetMemberName <Chart> (x => x.Series); item.Properties [propertyName] Collection.add (ColumnSeries);.}}}

.png)








Les commentaires récents