Voici un grand nombre de fonctionnalités cachées discutées pour une variété de langues. Maintenant, je suis curieux de connaître certaines fonctionnalités cachées de XAML et WPF?
Un que j'ai trouvé est l'événement de clic d'en-tête d'un ListView
<ListView x:Name='lv'
Height="150"
GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler">
La propriété GridViewColumnHeader.Click n'est pas répertoriée.
Certaines fonctionnalités pertinentes à ce jour:
Voir aussi:
Multibinding (combiné avec StringFormat):
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}, {1}">
<Binding Path="LastName" />
<Binding Path="FirstName" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Il existe également une astuce PresentationTraceSources.TraceLevel pour déboguer ce qui se passe avec les liaisons dans un scénario particulier. Tout ce que vous avez à faire est de référencer l'espace de noms System.Diagnostics dans WindowsBase Assembly
xmlns:sd="clr-namespace:System.Diagnostics;Assembly=WindowsBase"
puis ajoutez ce qui suit à l'expression de liaison:
<TextBlock Text="{Binding Message, sd:PresentationTraceSources.TraceLevel=High}" />
Le journal sera comme ceci:
System.Windows.Data Warning: 52 : Created BindingExpression (hash=5923895) for Binding (hash=7588182)
System.Windows.Data Warning: 54 : Path: 'Message'
System.Windows.Data Warning: 56 : BindingExpression (hash=5923895): Default mode resolved to OneWay
System.Windows.Data Warning: 57 : BindingExpression (hash=5923895): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 58 : BindingExpression (hash=5923895): Attach to System.Windows.Controls.TextBlock.Text (hash=65248697)
System.Windows.Data Warning: 63 : BindingExpression (hash=5923895): Resolving source
3.5sp1 a introduit StringFormat dans les expressions de liaison, par exemple.
<TextBox Text="{Binding Date, StringFormat='{}{0:MM/dd/yyyy}'}" />
3.5sp1 a introduit TargetNullValue aux liaisons. Cela définira la propriété liée sur Null si la valeur est entrée et si votre propriété est Null, elle affichera cette valeur.
<TextBox Text="{Binding Total, TargetNullValue=$0.00}" />
Parfois, vous obtenez une chaîne trop longue pour apparaître sur l'étiquette. Dans ce cas, nous pouvons utiliser TextTrimming
la propriété TextBlock
pour afficher les ellipses
<TextBlock
Name="sampleTextBlock"
TextTrimming="WordEllipsis"
TextWrapping="NoWrap"/>
<Window.Resources>
<ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml" />
</Window.Resources>
Génériques en XAML avec x: TypeArguments
Si vous souhaitez utiliser un ObservableCollection dans XAML, vous devez créer un type qui dérive de ObservableCollection car vous ne pouvez pas le déclarer dans XAML. Avec XAML 2009, vous pouvez utiliser l'attribut x: TypeArguments pour définir le type d'un type générique.
<!-- XAML 2006 -->
class EmployeeCollection : ObservableCollection<Employee>
{
}
<l:EmployeeCollection>
<l:Employee FirstName="John" Name="Doe" />
<l:Employee FirstName="Tim" Name="Smith" />
</lEmployeeCollection>
<!-- XAML 2009 -->
<ObservableCollection x:TypeArguments="Employee">
<l:Employee FirstName="John" Name="Doe" />
<l:Employee FirstName="Tim" Name="Smith" />
</ObservableCollection />
Afficher l'info-bulle sur un contrôle désactivé
Wpf permet d'afficher une info-bulle sur un contrôle, s'il est désactivé.
Par exemple
<Button Content="Disabled Button" ToolTipService.ShowOnDisabled="True" IsEnabled="False" ToolTip="This is a disabled button"/>
Utilisation de constructeurs non par défaut avec des arguments x:
Dans XAML 2006, les objets doivent avoir un constructeur public par défaut pour les utiliser. Dans XAML 2009, vous pouvez transmettre des arguments de constructeur à l'aide de la syntaxe x: Arguments.
<!-- XAML 2006 -->
<DateTime>00:00:00.0000100</DateTime>
<!-- XAML 2009 -->
<DateTime>
<x:Arguments>
<x:Int64>100</x:Int64>
</x:Arguments>
</DateTime>
Les extensions de balisage et les propriétés attachées sont mes fonctionnalités préférées, elles vous permettent d'étendre le "vocabulaire" XAML d'une manière très élégante.
Extensions de balisage
<!-- Binding to app settings -->
<CheckBox IsChecked="{my:SettingBinding MinimizeToTray}">Close to tray</CheckBox>
<!-- Fill ItemsControl with the values of an enum -->
<ComboBox ItemsSource="{my:EnumValues sys:DaysOfWeek}"/>
<!-- Localization -->
<TextBlock Text="{my:Localize HelloWorld.Text}"/>
<!-- Switch on the result of a binding -->
<TextBlock Text="{my:Switch Path=IsGood, ValueIfTrue=Good, ValueIfFalse=Bad}"/>
Propriétés attachées
<!-- Sort GridView automatically -->
<ListView ItemsSource="{Binding Persons}"
IsSynchronizedWithCurrentItem="True"
util:GridViewSort.AutoSort="True">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Name"
DisplayMemberBinding="{Binding Name}"
util:GridViewSort.PropertyName="Name"/>
<GridViewColumn Header="First name"
DisplayMemberBinding="{Binding FirstName}"
util:GridViewSort.PropertyName="FirstName"/>
<GridViewColumn Header="Date of birth"
DisplayMemberBinding="{Binding DateOfBirth}"
util:GridViewSort.PropertyName="DateOfBirth"/>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<!-- Vista Glass effect -->
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WpfApplication1"
Title="Window1"
my:WinUtil.EnableAeroGlass="True">
...
Source pour GridViewSort (btw, il utilise le GridViewColumnHeader.Click
événement mentionné par Ortus)
Pas vraiment une fonctionnalité cachée mais avec WPF/XAML, vous obtenez Bea Stollnitz et Josh Smith . Reine et roi de la programmation WPF/XAML.
Vous pouvez faire référence aux types imbriqués dans XAML à l'aide du signe plus (+
). Par exemple, si nous avions cette classe:
public class SomeClass
{
public enum SomeEnum
{
SomeValue
};
}
Nous pourrions faire référence à SomeValue
en XAML en utilisant la syntaxe suivante:
{x:Static local:SomeClass+SomeEnum.SomeValue}
Cette syntaxe est non documentée sur MSDN , et elle n'est pas officiellement prise en charge. Quelqu'un demandé à ce sujet sur les forums MSDN, et apparemment, il casse le concepteur WPF de VS2010. Il a a été signalé sur Microsoft Connect.
Partage de la taille de la grille ( voici un bon exemple). En bref, vous pouvez avoir des colonnes et des rangées de tailles de partage de grille, même sur différentes grilles. Cela sera inestimable pour toutes les personnes qui utilisent DataGrids sans avoir à modifier les données en place.
PriorityBinding. Vous permet d'utiliser les liaisons asynchrones dans un ordre "premier arrivé, premier arrivé":
<TextBlock.Text>
<PriorityBinding FallbackValue="defaultvalue">
<Binding Path="SlowestDP" IsAsync="True"/>
<Binding Path="SlowerDP" IsAsync="True"/>
<Binding Path="FastDP" />
</PriorityBinding>
</TextBlock.Text>
Utilisation de méthodes d'usine statiques avec x: FactoryMethod
Lorsque vous avez un type qui n'a pas de constructeur public mais une méthode d'usine statique, vous avez dû créer ce type dans le code dans XAML 2006. Avec XAML 2009, vous pouvez utiliser l'attribut x: FactoryMethodx: Arguments pour transmettre les valeurs d'argument.
<!-- XAML 2006 -->
Guid id = Guid.NewGuid();
<!-- XAML 2009 -->
<Guid x:FactoryMethod="Guid.NewGuid" />
Une autre chose qui n'est pas très claire est le contenu de certaines propriétés auxquelles nous sommes habitués ne contient que du texte. Si la propriété d'un élément GUI est de type Object, il est très probable que vous puissiez, au lieu de simplement définir le texte, ajouter un panneau de votre besoin qui comprend un ensemble de contrôles.
Un exemple de ceci est le MenuItem, où la propriété Header
(qui ne contient normalement que du texte) peut contenir un ensemble d'éléments gui enveloppés dans un contrôle de panneau (ou juste un élément gui si vous n'en avez besoin que d'un).
Notez également la propriété Icon
sur le MenuItem. Cela contient normalement un élément Image, mais cela peut aussi contenir n'importe quoi!
<MenuItem Name="MyMenuItem" Click="MyMenuItem_Click">
<MenuItem.Icon>
<Button Click="Button1_Click">i</Button>
</MenuItem.Icon>
<MenuItem.Header>
<StackPanel Orientation="Horizontal" >
<Label>My text</Label>
<Button Click="Button2_Click">ClickMe!</Button>
</StackPanel>
</MenuItem.Header>
</MenuItem>
Convertisseurs XAML
La liste suivante montre les convertisseurs développés par la communauté WPF pour convertir différents formats en XAML ou vice versa.
Plugin d'exportation Adobe Illustrator XAML
Adobe Photoshop en XAML Converter
Plugin d'exportation Blender XAML
Plugin d'exportation Lightwave XAML
<Border Background="{DynamicResource {x:Static SystemColors.InactiveBorderBrushKey}}"/>
Types intégrés
Si vous souhaitez ajouter des objets de types simples comme chaîne ou double à un dictionnaire de ressources aujourd'hui, vous devez mapper les espaces de noms clr nécessaires à des espaces de noms XML. Dans XAML 2009, nous avons beaucoup de types simples qui sont inclus dans le langage XAML.
<!-- XAML 2006 -->
<sys:String xmlns:sys="clr-namespace:System;Assembly=mscorlib >Test</sys:String>
<!-- XAML 2009 -->
<x:String>Test</x:String>
Les types suivants sont inclus dans le langage XAML:
<x:Object/>
<x:Boolean/>
<x:Char/>
<x:String/>
<x:Decimal/>
<x:Single/>
<x:Double/>
<x:Int16/>
<x:Int32/>
<x:Int64/>
<x:TimeSpan/>
<x:Uri/>
<x:Byte/>
<x:Array/>
<x:List/>
<x:Dictionary/>
Références d'objets faciles avec {x: Reference}
Si vous souhaitez créer une référence d'objet aujourd'hui, vous devez effectuer une liaison de données et déclarer la source avec un ElementName. Dans XAML 2009, vous pouvez utiliser la nouvelle extension de balisage {x: Reference}
<!-- XAML 2006 -->
<Label Target="{Binding ElementName=firstName}">FirstName</Label>
<TextBox x:Name="firstName" />
<!-- XAML 2009 -->
<Label Target="{x:Reference firstName}">FirstName</Label>
<TextBox x:Name="firstName" />
Prise en charge des clés de dictionnaire arbitraires
Dans XAML 2006, toutes les valeurs x: Key explicites étaient traitées comme des chaînes. Dans XAML 2009, vous pouvez définir tout type de clé que vous aimez en écrivant la clé dans ElementSyntax.
<!-- XAML 2006 -->
<StreamGeometry x:Key="CheckGeometry">M 0 0 L 12 8 l 9 12 z</StreamGeometry>
<!-- XAML 2009 -->
<StreamGeometry>M 0 0 L 12 8 l 9 12 z
<x:Key><x:Double>10.0</x:Double></x:Key>
</StreamGeometry>
Définir une ValidationError par code
Un ValidatioRule dans une BindingExpression ne se déclenche que lorsque le côté cible de la liaison change. Si vous souhaitez définir une erreur de validation par code, vous pouvez utiliser l'extrait de code suivant.
Définir l'erreur de validation
ValidationError validationError =
new ValidationError(regexValidationRule,
textBox.GetBindingExpression(TextBox.TextProperty));
validationError.ErrorContent = "This is not a valid e-mail address";
Validation.MarkInvalid(
textBox.GetBindingExpression(TextBox.TextProperty),
validationError);
Supprimer l'erreur de validation
Validation.ClearInvalid(textBox.GetBindingExpression(TextBox.TextProperty));
La possibilité de placer des UIElement (s) dans un TextBlock
Je ne sais pas à quel point cela est utile (il est qualifié de caché) ... mais cela m'a certainement pris au dépourvu quand je je l'ai rencontré pour la première fois :
<Grid x:Name="LayoutRoot">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid>
<Rectangle Fill="AliceBlue" Width="25" Height="25"/>
</Grid>
</TextBlock>
</Grid>
Vous pourriez faire valoir que le xaml suivant pourrait être utile (c'est-à-dire mettre un graphique à la fin d'un texte):
<Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Hello World">
<TextBlock.Resources>
<DrawingBrush x:Key="exclamationPoint" Stretch="Uniform">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="#FF375CE2" Geometry="F1 M 7.968,58.164L 0,58.164L 1.914,49.921L 9.882,49.921L 7.968,58.164 Z M 21.796,0L 11.054,42.148L 4.403,42.148L 13.049,0L 21.796,0 Z "/>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</TextBlock.Resources>
<Grid>
<Rectangle Width="100" Height="100" Fill="{StaticResource exclamationPoint}"/>
</Grid>
</TextBlock>
</Grid>
Le xaml ci-dessus se présente comme suit:
Liaison sans INotifyPropertyChanged ou DependencyProperties
Comme expliqué ici vous pouvez lier une propriété d'objet CLR simple sans INotifyPropertyChanged, et cela fonctionnera juste.
Voici le Forumpost dont je parle.
Citation:
[...] Le moteur de liaison de données de WPF liera les données à l'instance PropertyDescriptor qui encapsule la propriété source si l'objet source est un objet CLR simple et n'implémente pas l'interface INotifyPropertyChanged. Et le moteur de liaison de données essaiera de s'abonner à l'événement de modification de propriété via la méthode PropertyDescriptor.AddValueChanged (). Et lorsque l'élément lié aux données cible modifie les valeurs de propriété, le moteur de liaison de données appellera la méthode PropertyDescriptor.SetValue () pour retransférer la valeur modifiée à la propriété source, et il déclenchera simultanément l'événement ValueChanged pour informer les autres abonnés (dans ce cas, les autres abonnés seront les TextBlocks dans le ListBox.
Et si vous implémentez INotifyPropertyChanged, vous êtes entièrement responsable d'implémenter la notification de changement dans chaque setter des propriétés qui doit être des données liées à l'interface utilisateur. Sinon, le changement ne sera pas synchronisé comme prévu. [...]
Voici un autre grand et détaillé article sur le sujet.
Remarque cela ne fonctionne que lors de l'utilisation de la liaison . Si vous mettez à jour les valeurs à partir du code , la modification ne sera pas notifiée . [...]
L'implémentation d'INotifyPropertyChanged peut être un travail fastidieux de développement. Cependant, vous devrez peser ce travail par rapport à l'empreinte d'exécution (mémoire et CPU) de votre application WPF. L'implémentation d'INPC vous permettra d'économiser du CPU et de la mémoire d'exécution .
Débogage des animations
Erreurs courantes
Si vous obtenez l'erreur suivante: Impossible d'animer '(0). (1)' sur une instance d'objet immuable. il se peut que vous rencontriez l'une des limitations suivantes: