2010-11-08 4 views
1

Comment un AttachedProperty qui est une propriété unique définie par un élément parent propriétaire peut-il être défini avec plusieurs valeurs via plusieurs éléments enfants de ce parent?Comment un objet AttachedProperty peut-il avoir plusieurs valeurs?

Par exemple:

Si j'ai:

<DockPanel> 
    <CheckBox DockPanel.Dock="Top">Hello</CheckBox> 
    <CheckBox DockPanel.Dock="Bottom">World</CheckBox> 
</DockPanel> 

Ici, nous avons un seul élément DockPanel et il a une seule propriété Dock. Comment peut-il être réglé sur "Top" puis "Bottom" simultanément?

Répondre

3

Il finira dans une méthode qui ressemble à ceci

public class DockPanel : Panel 
{ 
    public static readonly DependencyProperty DockProperty; 
    // ... 
    public static void SetDock(UIElement element, Dock dock) 
    { 
     element.SetValue(DockProperty, value); 
    } 
} 

Comme vous pouvez le voir, il est en réalité pas mis sur le parent, mais le CheckBox lui-même, par la méthode SetDock statique sur DockPanel et non le parent exemple. Le faire dans le code derrière le rend un peu plus clair, notez comment nous n'utilisons jamais une instance d'un DockPanel.

DockPanel.SetDock(checkBox1, Dock.Top); 
DockPanel.SetDock(checkBox2, Dock.Bottom); 

Espérons que c'était clair, sauf si votre question était de savoir comment cela fonctionne "sous le capot". Dans ce cas, voir this question.

Citation du lien.

Le but de ce mécanisme est de « attacher » à d'autres objets d'informations nécessaires par les objets parents, pas les objets eux-mêmes enfants .

Une CheckBox n'a pas d'utilité pour une propriété Dock à moins qu'elle ne se trouve dans un DockPanel. Idem pour Grid.Row, Canvas.Left, Validation.HasError (lecture seule) etc. Donc, fondamentalement, le DockPanel est celui qui a besoin de l'information, mais il a besoin de tous ses enfants pour pouvoir le stocker. Par conséquent, il utilise une propriété attachée pour cela. Si vous créiez un nouveau Panel, appelé PuneetPanel, et que vous aviez besoin d'un Ange pour calculer la position enfant, vous pouviez définir votre propre Propriété attachée, PuneetPanel.Angel dans ce panneau et tous les enfants pouvaient l'utiliser sans avoir à être sous-classés.

+0

Donc, je ne comprends pas ce que l'utilisation de "AttachedProperty", que fait-il, cela pourrait aussi avoir été fait en utilisant une propriété sur CheckBox quand finalement il est stocké avec le CheckBox. Pourquoi DockPanel définit et possède la propriété et maintient un identifiant de propriété avec elle. – teenup

0

C'est une très bonne question. La réponse réside dans le fonctionnement de AttchedProperty. La propriété AttachedProperty est utilisée par le parent pour rendre un enfant. Avant de rendre l'enfant, le parent recherche toute propriété attachée définie sur l'enfant et s'applique à l'enfant.

Je trouve cela de msdn qui pourrait vous être utile ::

DockPanel définit la propriété DockPanel.Dock ci-joint, et DockPanel a un code de niveau de classe dans le cadre de sa logique de rendu (en particulier, MeasureOverride et ArrangerOverride).
Une instance DockPanel vérifie toujours si l'un de ses éléments enfants immédiats a défini une valeur pour DockPanel.Dock. Si oui, ces valeurs deviennent entrée pour la logique de rendu appliqué à cet élément d'enfant en particulier ....

Vous pouvez voir ce lien pour obtenir aperçu détaillé ::
http://http://msdn.microsoft.com/en-us/library/ms749011.aspx

espérons qu'il vous aidera !!

+0

J'ai déjà lu cette page msdn, à la lecture de cette page seulement, j'ai eu ce doute. Je sais que le parent interrogera les enfants pour cette propriété, mais dans quel objet les différentes valeurs de la propriété seront sauvegardées? Parce que la propriété est une variable membre unique dans la classe propriétaire et ne peut avoir qu'une seule valeur à la fois. Ce que je suppose est la propriété sera stockée séparément dans les deux cases à cocher dans cet exemple, mais le CheckBox n'a pas de propriété Dock lui-même. – teenup

+0

Oui, une propriété jointe ne peut avoir qu'une seule valeur à la fois pour une instance DependencyObject (CheckBox). Il ne sera pas stocké directement dans l'objet. Le moteur WPF gère une table de recherche en interne où chaque instance d'objet est liée aux propriétés attachées qui ont été définies. Lorsque vous obtenez les valeurs à l'aide de XAML ou de la méthode get accessor, vous faites en sorte que WPF recherche les valeurs dans la table. De l'extérieur, il * regarde * comme si vous aviez récupéré directement depuis l'objet. – bitbonk

0

Pour vos propres propriétés attachées personnalisées, il y a deux options pour réaliser ce que vous cherchez:

1. Si le nombre de combinaisons de valeurs définissables sont pas complexes, vous pouvez rendre votre propriété attachée de type enum qui a l'ensemble FlagsAttribute. Vous pouvez les moissonneuses-batteuses les valeurs que vous souhaitez définir à l'aide bitwise ou |:

[Flags] 
public enum MultiDock 
{ 
    Left, 
    Top, 
    Right, 
    Bottom 
} 

et son utilisation dans le code:

MyCustomPanelOrWhatever.SetMultiDock(MultiDock.Left | MultiDock.Bottom); 

Cela a une petite proplem cependant, vous ne pouvez pas faire ci-dessus en xaml directement, vous devrez écrire un MarkupExtension qui peut convertir la chaîne en valeurs énumérées. Son utilisation doit ressembler à ceci:

<CheckBox src:MyCustomPanelOrWhatever.MulitDock="{src:FlaggedEnum Left|Bottom}" /> 

2. Étant donné que les propriétés attachées peuvent être de tout type, ils peuvent bien sûr être aussi des types complexes (avec plusieurs sous-propriétés) ou même des collections, il est facilement possible de faire quelque chose comme ceci:

MyCustomPanelOrWhatever.SetMultiDock(new List<MultiDock> { MultiDock.Left, MultiDock.Bottom }); 

Si vous avez défini votre propriété jointe de cette façon, vous ne pas besoin de convertisseurs pour XAML, vous pouvez l'utiliser directement:

<CheckBox> 
    <src:MyCustomPanelOrWhatever.MultiDock> 
     <src:MultiDock.Left/> 
     <src:MultiDock.Bottom/> 
    </src:MyCustomPanelOrWhatever.MultiDock> 
</CheckBox> 
Questions connexes