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 remet en question la réponse.
<object ...>
<x:Arguments>
oneOrMoreObjectElements
</x:Arguments>
</object>
Je me rends compte que je suis en retard à la fête ici, mais comme personne n'a vraiment abordé les conventions WPF, je pensais que j'interviendrais.
L'un des principes directeurs des objets compatibles avec XAML est qu'ils doivent être complètement utilisables avec un constructeur par défaut, c'est-à-dire qu'aucun comportement n'est accessible uniquement lors de l'utilisation d'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 paramètres de propriété. Il existe également une convention qui dit que l'ordre dans lequel les propriétés sont définies dans XAML ne devrait pas être important.
Cependant, vous pouvez avoir des considérations spéciales qui sont importantes pour votre mise en œuvre mais en contradiction avec la convention:
StreamSource
et UriSource
d'une image.Pour faciliter la gestion de ces cas, l'interface ISupportInitialize
est fournie. Lorsqu'un objet est lu et créé à partir de XAML (c'est-à-dire analysé), les objets implémentant ISupportInitialize
seront traités spécialement:
BeginInit()
sera appelée.EndInit()
est appelée.En suivant les 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 de 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.
Non. Pas de XAML [lors de l'utilisation de WPF].
Oui, vous pouvez le faire par le 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 le ConstructorParameters
. Voir une solution de contournement ici .