4

Voici l'affaire. Je peux créer un ListBox et le styler. Je peux éditer une copie du modèle de sorte que les états deviennent disponibles dans Expression Blend 3. Et je peux changer l'état de sorte que la couleur d'arrière-plan d'un élément de ligne soit modifiée quand elle est sélectionnée. Mais je ne peux pas changer la couleur de premier plan du texte à cause du ContentPresenter! Quelqu'un at-il un exemple XAML qui montre comment accomplir cette tâche apparemment facile?Comment puis-je utiliser VisualStateManager pour modifier la couleur du texte (premier plan) d'un ListBoxItem?

La réponse semble résider dans la suppression du ContentPresenter et son remplacement par un style ou un modèle de ListBoxItem, mais c'est là que je suis bloqué. Le ContentPresenter de ListBox fait référence à un autre modèle "{TemplateBinding Template}" - où est-ce? En outre, lorsque j'essaie de modifier ContentPresenter de quelque manière que ce soit, le panneau Etats est vide et il me reste un bourrelet de XAML. Heureusement, il y a CTRL-Z! Je pense vraiment que Microsoft doit repenser l'approche XAML ou faire de Blend un outil beaucoup plus complet. La façon dont cela devrait fonctionner est que je devrais pouvoir cliquer sur n'importe quel élément et en définir les états. Si j'essaie d'enfreindre les règles, Blend devrait me le dire et proposer un moyen de le réparer. Il ne sert à rien d'avoir le panneau États vide.

Répondre

1

Ordinairement le ListBox est pas responsable du contenu des articles eux-mêmes, y compris ce que Foreground couleur, le cas échéant, ils utilisent. Les éléments peuvent être une série d'images, auquel cas Foreground n'a pas de sens. Les éléments peuvent être une interface utilisateur complexe à plusieurs éléments contenant différents éléments de texte ayant chacun besoin de couleurs différentes. L'idée de ListBox fournissant une seule couleur Foreground n'a donc aucun sens. C'est pourquoi le modèle par défaut du conteneur Item utilise un ContentPresenter, ce qui signifie en gros "placer le contenu d'un élément arbitraire ici".

Si vous souhaitez créer un nouveau style pour les zones de liste en général à utiliser pour leurs styles d'éléments de conteneur, vous devez accepter cette limitation, votre VSM ne peut pas connaître les détails de l'élément contenu.

Toutefois, si vous créez un style de conteneur pour une instance spécifique de ListBox et que vous comprenez le type et la nature des éléments présentés, vous n'avez pas besoin de conserver le ContentPresenter dans le modèle. Vous pouvez remplacer directement avec ce que jamais Xaml vous devez présenter chaque élément.

Par exemple, vous pouvez remplacer le ContentPresenter dans le XAML avec ceci: -

<Grid Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"> 
    <TextBlock x:Name="ContentItem" Text="{Binding Property1, Mode=OneWay}" TextWrapping="Wrap" Foreground="#FFDC1C1C"/> 
</Grid> 

Notez que la Rembourrage et HorizontalAlignment des articles sont les mêmes que ceux utilisés par le présentateur. Dans ce cas, j'utilise comme unique TextBlock appelé "ContentItem" et le lier à la propriété Property1 des objets source.

Maintenant que le modèle contient un TextBlock nommé pour afficher l'élément, je peux bidouiller le VSM pour modifier son Foreground pour différents états visuels.

+0

J'ai remplacé ContentPresenter par un DataTemplate personnalisé composé d'un contrôle utilisateur. Ce contrôle a un bloc de texte. Pour que VSM fonctionne, je dois d'une manière ou d'une autre obtenir une référence à l'instance de contrôle personnalisée réelle lorsque listbox déclenche l'événement SelectionChanged. C'est problématique. La méthode VSM.GoToState nécessite que l'instance lui soit transmise afin qu'elle puisse fonctionner. Je n'arrive pas à obtenir la référence. Des idées? Je suis d'accord que vous devriez être en mesure de «jouer avec le VSM» pour faire ce travail, mais devrait être le mot optimal, ici. Je dois encore voir quelqu'un le faire, cependant. – Wade

+0

Maintenant, je peux capturer chaque instance DataTemplate personnalisée dans un tableau lors de l'événement Loaded du contrôle, puis utiliser des index numériques pour trouver l'instance basée sur la propriété SelectedIndex de la ListBox parent, mais cela est difficilement extensible. – Wade

+0

Eh bien, j'ai trouvé un moyen de le faire sans utiliser VSM mais cela élimine la possibilité de jouer des animations. Je suis passé à Foreground du bloc de texte à {TemplateBinding Foreground}, puis définissez Foreground sur le ListBoxItem. Soupir .... – Wade

1

Désolé de ressusciter une vieille question, mais je suis resté coincé sur le même problème et trouvé une solution. Je vais le partager, car qui sait, cela peut être utile à quelqu'un.

C'est très simple: si vous remplacez ContentPresenter dans votre modèle par ContentControl, cela fonctionne (ContentControl a une propriété Foreground).

0

Ah, cool! Merci pour les commentaires. Je pense que j'ai fini par faire un contrôle de l'utilisateur et exposer une propriété publique d'avant-plan qui définit la couleur, mais je ne me souviens pas. Votre réponse combinée avec la précédente est vraiment utile. En aparté, je suis tombé en panne et j'ai appris à faire mes propres contrôles personnalisés avec des propriétés de dépendance et les 9 yards entiers et, mec, lemme vous le dire, ça valait le coup. Je me sens comme je peux faire n'importe quoi avec WPF/SL maintenant.

Questions connexes