J'ai un contrôle personnalisé qui est utilisé dans un formulaire, ce contrôle combine une étiquette et une zone de texte. Lorsque le formulaire est en mode lecture seule, le contrôle est modifié pour afficher une étiquette au lieu de la zone de texte. Pour ce faire, j'ai défini un modèle de contenu pour mon contrôle, comme suit :
<Style TargetType="{x:Type Controls:FormFieldControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<AdornerDecorator Grid.Column="1"
Visibility="{Binding RelativeSource={RelativeSource AncestorType=Controls:FormFieldControl},
Path=IsReadOnly,
Converter={StaticResource BooleanToInverseVisibilityConverter},
Mode=OneWay}">
<ContentPresenter Name="ContentPresenter" />
</AdornerDecorator>
<AdornerDecorator Grid.Column="1"
Visibility="{Binding RelativeSource={RelativeSource AncestorType=FormFieldControl},
Path=IsReadOnly, Converter={StaticResource BooleanToVisibilityConverter},
Mode=OneWay}">
<ContentPresenter Name="ReadOnlyContentPresenter" />
</AdornerDecorator>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
ReadOnlyContentPresenter
est une étiquette à laquelle on a appliqué le style suivant :
<Style x:Key="ReadOnlyFormFieldControl" TargetType="{x:Type Label}">
<Setter Property="Width" Value="400" />
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Controls:FormFieldControl},
Path=ReadOnlyWidth,
Converter={StaticResource IsSetConverter}}"
Value="True">
<Setter Property="Width"
Value="{Binding RelativeSource={RelativeSource AncestorType=Controls:FormFieldControl}, Path=ReadOnlyWidth}" />
</DataTrigger>
</Style.Triggers>
</Style>
Cela fonctionne bien pour environ 80 contrôles, mais lorsque j'ajoute d'autres contrôles au formulaire, la liaison dans le style de l'étiquette ne trouve pas la source (erreur 4) :
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='MyProject.Controls.FormFieldControl', AncestorLevel='1''. BindingExpression:Path=ReadOnlyWidth; DataItem=null; target element is 'Label' (Name=''); target property is 'ReadOnlyWidth' (type 'Double?')
La même chose se produit avec le style appliqué à la partie modifiable du contrôle. Je pense que le problème est lié à la quantité de contrôles traités, si je déplace le code du contrôle no. 81 (défaillant) juste au-dessus du contrôle no. 80 (qui fonctionne), la liaison dans le contrôle n° 81 fonctionne maintenant, mais celle dans le contrôle n° 80 ne fonctionne pas. 81 fonctionne maintenant, mais celle du contrôle n° 80 échoue. 80 échoue. J'ai fait cela pour plusieurs contrôles, et le comportement est cohérent.
Je n'ai toujours pas compris comment les AdornerDecorator
fonctionne exactement, et en enquêtant j'ai trouvé ceci question qui mentionne un problème avec le fait d'avoir plus de 144 parures dans un adornerlayer, j'ai donc supprimé le fichier AdornerDecorator
dans mon code, pour constater que le problème de liaison qui se produisait pour les contrôles n'était plus. 81 et plus se produit maintenant pour tous mes contrôles FormFieldControl
's.
Finalement, j'ai décidé d'essayer avec ContentControl
au lieu de ContentPresenter
dans mon modèle de contrôle. Cela fonctionne bien pour tous les contrôles du formulaire. Je sais que ContentPresenter
est une forme allégée de ContentControl
et qu'il est plus approprié de l'utiliser à l'intérieur d'un modèle de contenu que l'option ContentControl
est. Cependant, je ne comprends pas bien pourquoi les liaisons échouent lorsque l'on utilise un fichier ContentPresenter
et de travailler en utilisant un ContentControl
.
Je trouve également étrange que seul un ensemble limité de commandes fonctionne et que, lorsqu'on n'utilise pas l'AdornerDecorator, aucune d'entre elles ne trouve la source de liaison.
Quelqu'un a-t-il rencontré quelque chose de similaire ? Est-ce que je fais quelque chose de mal avec l'outil ContentPresenter
? Ou si c'est un comportement attendu, quelqu'un pourrait-il m'aider à comprendre ce qui se passe ?
Toute idée est la bienvenue.