2010-05-10 4 views
0

Je voudrais créer un ensemble de contrôles personnalisés qui sont essentiellement des boutons d'image (c'est un peu plus complexe que cela, mais c'est l'effet sous-jacent que je vais faire) que j'ai vu quelques exemples différents pour. Cependant, je voudrais étendre cela pour permettre également les boutons radio/bascule. Ce que je voudrais faire est d'avoir une classe abstraite commune appelée ImageButtonBase qui a des implémentations par défaut pour ImageSource et Text, etc. Cela rend une implémentation régulière d'ImageButton assez facile.Bouton d'image personnalisée et bouton radio/bascule de la classe de base commune

Le problème que j'ai est de créer la saveur RadioButton de celui-ci. Comme je le vois, il y a au moins trois options:

  1. Il serait facile de créer quelque chose qui dérive de RadioButton, mais je ne peux pas utiliser la classe abstraite que j'ai créée.
  2. Je pourrais changer la classe abstraite à une interface, mais ensuite je perds les implémentations abstraites , et aura en fait une duplication de code.
  3. Je pourrais dériver de ma classe abstraite, et ré-implémenter les propriétés et événements de type RadioButton (IsChecked, GroupName, etc.), mais cela ne semble certainement pas une bonne idée.

Note: J'ai vu How to get a group of toggle buttons to act like radio buttons in WPF?, mais ce que je veux faire est un peu plus complexe. Je me demande simplement si quelqu'un a un exemple de mise en œuvre, ou quelque chose qui pourrait être adapté à ce genre de scénario. Je peux voir les avantages et les inconvénients de chacune des idées ci-dessus, mais chacun vient avec des pièges potentiels.

Merci, WTS

+0

Pour moi, c'est confus, vous voulez créer un seul contrôle, qui peut être un bouton (associé à une commande?), Un bouton bascule (lié à un bool?) Ou un bouton radio (lié à un type intégral) ? Je ne pense pas qu'il existe une solution pour les obtenir tous sans introduire trop d'écarts de comportement et d'autres odeurs de code. Si c'est le cas, il vaut probablement mieux créer une classe distincte pour chaque objectif. Vous pouvez toujours les laisser étendre une interface-marqueur, si vous voulez leur donner des propriétés communes. –

+0

Non, c'est plus que je veux plusieurs contrôles basés sur une seule classe abstraite. Le framework fait la même chose - il y a le contrôle ButtonBase, qui est hérité par les contrôles Button et ToggleButton. RadioButton dérive alors de ToggleButton. Je veux créer une classe abstraite dérivée de ButtonBase, avec mes propriétés supplémentaires. Mes classes de classe Button et RadioButton en dériveraient. La chose que j'essaie d'éviter, si possible, est de redéfinir toutes les propriétés et les événements de RadioButton que je recevrais «gratuitement». –

Répondre

1

Je pense que la meilleure solution est d'utiliser les propriétés attachées au lieu de sous-classement. Cela vous permettra d'avoir votre gâteau et de le manger aussi.

Au lieu d'écrire ceci:

<my:CustomButton ImageSource="Abc" Text="Def" ... /> 

vous pouvez écrire ceci:

<Button my:ButtonLook.ImageSource="Abc" my:ButtonLook.Text="Def" ... /> 

Cela fonctionne avec une liaison et tout données. Pour implémenter cela, créez votre classe "ButtonLook" dérivant de DependencyObject, et créez les deux propriétés jointes en utilisant l'extrait "propa" dans Visual Studio. Ensuite, définissez un PropertyChangedCallback sur chaque construction pour mettre à jour la propriété ContentControl.Content sur tout ce à quoi ils sont attachés.

Une autre solution consiste à incorporer un RadioButton caché dans votre sous-classe CustomRadioButton, donnez-lui un modèle vide pour le rendre invisible, et lier les propriétés isChecked et GroupName:

<ControlTemplate TargetType="my:CustomRadioButton"> 
    <Grid> 
    <RadioButton IsChecked="{Binding ToggleButton.IsChecked, RelativeSource={RelativeSource TemplatedParent}}" 
       GroupName="{TemplateBinding GroupName}"> 
     <RadioButton.Template><ControlTemplate /></RadioButton.Template> 
    </RadioButton> 
    ... visual part here ... 

Assurez-vous que votre CustomToggleButton et CustomRadioButton les sous-classes utilisent AddOwner pour créer DependencyProperties telles que IsChecked et GroupName plutôt que d'en créer de nouvelles.

+0

J'essaie la route des propriétés jointes, mais je ne comprends pas ce que vous voulez dire à propos de PropertyChangedHandler. Le seul autre "problème" que j'ai avec cette solution est que je voudrais toujours les intégrer dans un contrôle personnalisé (ou utilisateur), de sorte qu'il peut être réutilisé plus facilement (ma classe abstraite réelle a beaucoup plus de propriétés, et ce serait Je peux facilement créer des propriétés dans un contrôle personnalisé et les lier aux propriétés attachées, mais cela me ramène juste dans la même situation que mon problème d'origine: –

+0

Je voulais dire PropertyChangedCallback Comme dans 'DependencyProperty.RegisterAttached (..., new PropertyMetadata {PropertyChangedCallback = (obj, e) => {votre_code-ici;}});' Je mettrai à jour la réponse, mais du reste de votre commentaire, il Il me semble que ma deuxième suggestion sera peut-être plus appropriée à vos besoins –

+0

Donc, pour être sûr que je suis clair, je vais encore devoir définir les propriétés, événements, etc. de RadioButton (ou ToggleButton) dans mon classe personnalisée? –

Questions connexes