tutorial - xaml wpf




Appel d'un constructeur paramétré à partir de XAML (3)

Lors de l'utilisation de WPF, j'ai remarqué que lorsque j'ajoute un contrôle à un fichier XAML, le constructeur par défaut est appelé.

Existe-t-il un moyen d'appeler un constructeur paramétré?


.NET 4.0 apporte une nouvelle fonctionnalité qui défie la réponse.

x: Arguments Directive

<object ...>
    <x:Arguments>
        oneOrMoreObjectElements
    </x:Arguments>
</object>

Je me rends compte que je suis en retard à la fête ici, mais comme personne ne s'est vraiment penché sur les conventions de WPF, j'ai pensé que je me ferais remarquer.

L'un des principes directeurs des objets compatibles XAML est qu'ils doivent être complètement utilisables avec un constructeur par défaut, c'est-à-dire qu'il n'y a pas de comportement qui n'est accessible que lorsqu'on utilise un constructeur non-par défaut. Pour s'adapter à la nature déclarative de XAML, les paramètres d'objet sont spécifiés via des setters de propriétés. Il existe également une convention qui stipule que l'ordre dans lequel les propriétés sont définies dans XAML ne doit pas être important.

Vous pouvez, cependant, avoir des considérations spéciales qui sont importantes pour votre implémentation, mais en contradiction avec la convention:

  1. Vous pouvez avoir une ou plusieurs propriétés qui doivent être définies avant que l'objet puisse être utilisé.
  2. Deux propriétés ou plus peuvent StreamSource mutuellement, par exemple, cela n'a aucun sens de définir à la fois le StreamSource et l' UriSource d'une image.
  3. Vous souhaiterez peut-être vous assurer qu'une propriété est définie uniquement lors de l'initialisation.
  4. Une propriété peut dépendre d'une autre, ce qui peut être difficile en raison de la convention d'indépendance des commandes mentionnée ci-dessus lors de la définition des propriétés.

Pour faciliter la gestion de ces cas, l'interface ISupportInitialize est fournie. Lorsqu'un objet est lu et créé à partir de XAML (par exemple, analysé), les objets implémentant ISupportInitialize seront traités spécialement:

  1. Le constructeur par défaut sera appelé.
  2. BeginInit() sera appelé.
  3. Les propriétés seront définies dans l'ordre dans lequel elles sont apparues dans la déclaration XAML.
  4. EndInit() est appelé.

En BeginInit() suivi des appels à BeginInit() et EndInit() , vous pouvez gérer toutes les règles que vous devez imposer, y compris l'exigence que certaines propriétés soient définies. C'est ainsi que vous devez gérer les paramètres de création. pas en exigeant des arguments constructeur.

Notez que ISupportInitializeNotification est également fourni, ce qui étend l'interface ci-dessus en ajoutant une propriété IsInitialized et un événement Initialized . Je recommande d'utiliser la version étendue.


Oui, vous pouvez le faire par ObjectDataProvider . Il vous permet d'appeler un constructeur non par défaut, par exemple:

<Grid>
    <Grid.Resources>
        <ObjectDataProvider x:Key="myDataSource"
                            ObjectType="{x:Type local:Person}">
            <ObjectDataProvider.ConstructorParameters>
                <system:String>Joe</system:String>
            </ObjectDataProvider.ConstructorParameters>
        </ObjectDataProvider>
    </Grid.Resources>
    <Label Content="{Binding Source={StaticResource myDataSource}, Path=Name}"></Label>
</Grid>

en supposant que la personne est

public class Person
{
    public Person(string Name)
    {
        this.Name = Name;
    }
    public string Name { get; set; }
}

Malheureusement, vous ne pouvez pas lier les ConstructorParameters . Voir une solution de contournement here .





xaml