web-dev-qa-db-fra.com

Fonctionnalités cachées de WPF et XAML?

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:

  1. Fonctionnalités cachées de C #
  2. Fonctionnalités cachées de Python
  3. Fonctionnalités cachées d'ASP.NET
  4. Fonctionnalités cachées de Perl
  5. Fonctionnalités cachées de Java
  6. Fonctionnalités cachées de VB.NET
  7. Fonctionnalités cachées de PHP
  8. Fonctionnalités cachées de Ruby
  9. Caractéristiques cachées de C
  10. Et ainsi de suite ........
123
Sauron

Multibinding (combiné avec StringFormat):

<TextBlock>
  <TextBlock.Text>
    <MultiBinding StringFormat="{}{0}, {1}">
      <Binding Path="LastName" />
      <Binding Path="FirstName" />
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>
87
Julien Poulin

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 
58
idursun

3.5sp1 a introduit StringFormat dans les expressions de liaison, par exemple.

<TextBox Text="{Binding Date, StringFormat='{}{0:MM/dd/yyyy}'}" />
44
Bryan Anderson

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}" />
44
Bryan Anderson

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"/>

Lien MSDN

29

Ajout d'un effet Aero à la fenêtre

  <Window.Resources>
    <ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, 
        PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml" />
</Window.Resources>
27
Sauron

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 />
21
Sauron

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"/> 
19
Sauron

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>
19
Sauron

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)

18
Thomas Levesque

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.

18
Bryan Anderson

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.

15
M. Dudley

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.

14
Bryan Anderson

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>
11
Sergey Aldoukhov

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" />
10
Sauron

Propriétés avancées de "légende"

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>
7
awe
7
Sauron

Utilisation des couleurs du système

<Border Background="{DynamicResource {x:Static SystemColors.InactiveBorderBrushKey}}"/>
6
SeeSharp

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/> 
6
Sauron

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" />
6
Sauron

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>
3
Sauron

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));
2
Sauron

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:

Hello World

2
cplotts

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 .

1
UrbanEsc

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:

  • Vous animez une propriété de dépendance sans définir de valeur locale
  • Vous animez une propriété de dépendance dont la valeur actuelle est définie dans un autre assembly qui n'est pas fusionné dans le dictionnaire de ressources.
  • Vous animez une valeur actuellement liée aux données
1
Sauron