Delen via


Overzicht van bijgevoegde eigenschappen

Een gekoppelde eigenschap is een concept dat wordt gedefinieerd door XAML. Een gekoppelde eigenschap is bedoeld om te worden gebruikt als een type globale eigenschap die is ingesteld voor een afhankelijkheidsobject. In Windows Presentation Foundation (WPF) worden gekoppelde eigenschappen doorgaans gedefinieerd als een gespecialiseerde vorm van afhankelijkheidseigenschap die niet beschikt over de conventionele eigenschap 'wrapper'.

Vereisten

In dit artikel wordt ervan uitgegaan dat u afhankelijkheidseigenschappen begrijpt vanuit het perspectief van een consument van bestaande afhankelijkheidseigenschappen in WPF-klassen (Windows Presentation Foundation) en dat u het overzicht van afhankelijkheidseigenschappen hebt gelezen. Als u de voorbeelden in dit artikel wilt volgen, moet u ook XAML begrijpen en weten hoe u WPF-toepassingen schrijft.

Waarom gekoppelde eigenschappen gebruiken

Eén doel van een gekoppelde eigenschap is om verschillende onderliggende elementen toe te staan unieke waarden op te geven voor een eigenschap die is gedefinieerd in een bovenliggend element. Een specifieke toepassing van dit scenario is dat onderliggende elementen het bovenliggende element laten weten hoe ze moeten worden gepresenteerd in de gebruikersinterface (UI). Een voorbeeld hiervan is de eigenschap DockPanel.Dock. De eigenschap DockPanel.Dock wordt gemaakt als een gekoppelde eigenschap, omdat deze is ontworpen om in te stellen op elementen die zijn opgenomen in een DockPanel in plaats van op DockPanel zelf. De DockPanel-klasse definieert het statische DependencyProperty veld met de naam DockPropertyen levert vervolgens de GetDock- en SetDock-methoden als openbare toegangsrechten voor de gekoppelde eigenschap.

Gekoppelde eigenschappen in XAML-

In XAML stelt u gekoppelde eigenschappen in met behulp van de syntaxis AttachedPropertyProvider.PropertyName-

Hier volgt een voorbeeld van hoe u DockPanel.Dock kunt instellen in XAML:

<DockPanel>
    <TextBox DockPanel.Dock="Top">Enter text</TextBox>
</DockPanel>

Het gebruik is enigszins vergelijkbaar met een statische eigenschap; U verwijst altijd naar het type DockPanel dat eigenaar is van en registreert de gekoppelde eigenschap, in plaats van te verwijzen naar een exemplaar dat is opgegeven met de naam.

Omdat een gekoppelde eigenschap in XAML een kenmerk is dat u instelt in markeringen, heeft alleen de setbewerking relevantie. U kunt een eigenschap niet rechtstreeks ophalen in XAML, hoewel er enkele indirecte mechanismen zijn voor het vergelijken van waarden, zoals triggers in stijlen (zie Styling en Templating).

Implementatie van gekoppelde eigenschap in WPF

In Windows Presentation Foundation (WPF) worden de meeste aan de gebruikersinterface gerelateerde gekoppelde eigenschappen op WPF-typen geïmplementeerd als afhankelijkheidseigenschappen. Gekoppelde eigenschappen zijn een XAML-concept, terwijl afhankelijkheidseigenschappen een WPF-concept zijn. Omdat gekoppelde WPF-eigenschappen afhankelijkheidseigenschappen zijn, bieden ze ondersteuning voor concepten van afhankelijkheidseigenschappen, zoals metagegevens van eigenschappen en standaardwaarden van die eigenschapsmetagegevens.

Hoe gekoppelde eigenschappen worden gebruikt door het type eigenaar

Hoewel gekoppelde eigenschappen op een object zijn ingesteld, betekent dit niet automatisch dat het instellen van de eigenschap een tastbaar resultaat oplevert of dat de waarde ooit door een ander object wordt gebruikt. Over het algemeen zijn gekoppelde eigenschappen bedoeld, zodat objecten die afkomstig zijn van een groot aantal mogelijke klassenhiërarchieën of logische relaties, algemene informatie kunnen rapporteren aan het type dat de gekoppelde eigenschap definieert. Het type dat de gekoppelde eigenschap definieert, volgt doorgaans een van deze modellen:

  • Het type dat de gekoppelde eigenschap definieert, is zo ontworpen dat het het bovenliggende element van de elementen kan zijn waarmee waarden voor de gekoppelde eigenschap worden ingesteld. Het type doorloopt vervolgens zijn kindobjecten via interne logica binnen een objectboomstructuur, haalt de waarden op en verwerkt die waarden op een bepaalde manier.

  • Het type dat de gekoppelde eigenschap definieert, wordt gebruikt als kinder-element voor diverse mogelijke bovenliggende elementen en inhoudsmodellen.

  • Het type dat de gekoppelde eigenschap definieert, vertegenwoordigt een service. Andere typen stellen waarden in voor de gekoppelde eigenschap. Wanneer vervolgens het element dat de eigenschap instelt, wordt geëvalueerd in de context van de service, worden de gekoppelde eigenschapswaarden verkregen via interne logica van de serviceklasse.

Een voorbeeld van een Parent-Defined gekoppelde eigenschap

Het meest voorkomende scenario waarbij WPF een gekoppelde eigenschap definieert, is wanneer een bovenliggend element een verzameling onderliggende elementen ondersteunt en ook een gedrag implementeert waarbij de specifieke kenmerken van het gedrag afzonderlijk worden gerapporteerd voor elk onderliggend element.

DockPanel definieert de gekoppelde eigenschap DockPanel.Dock en DockPanel heeft code op klasseniveau als onderdeel van de renderinglogica (met name MeasureOverride en ArrangeOverride). Een DockPanel-exemplaar controleert altijd om te zien of een van zijn directe kindelementen een waarde voor DockPanel.Dockheeft ingesteld. Als dat het geval is, worden deze waarden invoer voor de weergavelogica die op dat specifieke kindelement wordt toegepast. Geneste DockPanel-exemplaren behandelen elk hun eigen verzamelingen van directe kindelementen, maar dat gedrag is specifiek voor de implementatie van hoe DockPanel de DockPanel.Dock-waarden verwerkt. Het is theoretisch mogelijk om gekoppelde eigenschappen te hebben die invloed hebben op elementen buiten het directe bovenliggende element. Als de gekoppelde eigenschap DockPanel.Dock is ingesteld op een element dat geen DockPanel bovenliggend element heeft om hierop te reageren, wordt er geen fout of uitzondering gegenereerd. Dit betekent simpelweg dat er een globale eigenschapswaarde is ingesteld, maar er geen huidige DockPanel ouder is die de informatie kan gebruiken.

Gekoppelde eigenschappen in code

Gekoppelde eigenschappen in WPF hebben niet de gebruikelijke CLR "wrapper"-methoden voor eenvoudige ophalen/instellen toegang. Dit komt doordat de gekoppelde eigenschap niet noodzakelijkerwijs deel uitmaakt van de CLR-naamruimte voor exemplaren waarin de eigenschap is ingesteld. Een XAML-processor moet deze waarden echter kunnen instellen wanneer XAML wordt geparseerd. Voor een effectief gebruik van gekoppelde eigenschappen moet het eigenaartype van de gekoppelde eigenschap de toegewezen toegangsmethoden implementeren in de vorm HaalEigenschapsnaam en StelEigenschapsnaam. Deze toegewezen toegangsmethoden zijn ook handig om de gekoppelde eigenschap in code op te halen of in te stellen. Vanuit codeperspectief is een gekoppelde eigenschap vergelijkbaar met een back-upveld met methodetoegangsors in plaats van eigenschapstoegangsors, en dat back-upveld kan bestaan op elk object in plaats van specifiek te moeten worden gedefinieerd.

In het volgende voorbeeld ziet u hoe u een gekoppelde eigenschap in code kunt instellen. In dit voorbeeld is myCheckBox een exemplaar van de klasse CheckBox.

DockPanel myDockPanel = new DockPanel();
CheckBox myCheckBox = new CheckBox();
myCheckBox.Content = "Hello";
myDockPanel.Children.Add(myCheckBox);
DockPanel.SetDock(myCheckBox, Dock.Top);
Dim myDockPanel As New DockPanel()
Dim myCheckBox As New CheckBox()
myCheckBox.Content = "Hello"
myDockPanel.Children.Add(myCheckBox)
DockPanel.SetDock(myCheckBox, Dock.Top)

Net als in het XAML-geval zou de vijfde coderegel geen uitzondering veroorzaken als myCheckBox nog niet was toegevoegd als onderliggend element van myDockPanel door de vierde coderegel, maar zou de eigenschapswaarde niet communiceren met een bovenliggende DockPanel en zou dus niets doen. Alleen een DockPanel.Dock-waarde die is ingesteld op een subelement, in combinatie met een aanwezige DockPanel-bovenliggend element, zorgt voor effectief gedrag in de toepassing. (In dit geval kunt u de gekoppelde eigenschap instellen en vervolgens koppelen aan de structuur. U kunt ook koppelen aan de structuur en vervolgens de gekoppelde eigenschap instellen. Beide actievolgordes bieden hetzelfde resultaat.)

Metagegevens van gekoppelde eigenschap

Bij het registreren van de eigenschap wordt FrameworkPropertyMetadata ingesteld om kenmerken van de eigenschap op te geven, zoals of de eigenschap van invloed is op rendering, meting enzovoort. Metagegevens voor een gekoppelde eigenschap verschillen over het algemeen niet van een afhankelijkheidseigenschap. Als u een standaardwaarde opgeeft in een overschrijving van de metagegevens van gekoppelde eigenschappen, wordt die waarde de standaardwaarde van de impliciete gekoppelde eigenschap voor instanties van de overschrijvende klasse. Specifiek wordt uw standaardwaarde gerapporteerd wanneer sommige processen de waarde van een gekoppelde eigenschap opvragen via de Get methode-accessor voor die eigenschap, door een instantie van de klasse te specificeren waarin u de metadata hebt gespecificeerd, en waarbij de waarde voor die gekoppelde eigenschap anders niet was ingesteld.

Als u overname van eigenschapswaarden voor een eigenschap wilt inschakelen, moet u gekoppelde eigenschappen gebruiken in plaats van niet-gekoppelde afhankelijkheidseigenschappen. Zie overname van eigenschapswaardenvoor meer informatie.

Aangepaste gekoppelde eigenschappen

Wanneer een gekoppelde eigenschap maken?

U kunt een gekoppelde eigenschap maken wanneer er een reden is om een mechanisme voor eigenschapsinstelling beschikbaar te hebben voor andere klassen dan de definiërende klasse. Het meest voorkomende scenario hiervoor is indeling. Voorbeelden van bestaande indelingseigenschappen zijn DockPanel.Dock, Panel.ZIndexen Canvas.Top. Het scenario dat hier is ingeschakeld, is dat elementen die bestaan als onderliggende elementen voor elementen voor indelingsbeheer, de indelingsvereisten afzonderlijk kunnen uitdrukken voor de bovenliggende elementen van de indeling, waarbij elke eigenschapswaarde wordt ingesteld die door het bovenliggende element is gedefinieerd als een gekoppelde eigenschap.

Een ander scenario voor het gebruik van een gekoppelde eigenschap is wanneer uw klasse een service vertegenwoordigt en u wilt dat klassen de service transparanter kunnen integreren.

Een ander scenario is het ontvangen van ondersteuning voor Visual Studio WPF Designer, zoals Eigenschappen vensterbewerking. Zie Overzicht van het ontwerpen van besturingselementenvoor meer informatie.

Zoals eerder vermeld, moet u zich registreren als een gekoppelde eigenschap als u overname van eigenschapswaarden wilt gebruiken.

Hoe een gekoppelde eigenschap maken

Als uw klasse de gekoppelde eigenschap strikt definieert voor gebruik op andere typen, hoeft de klasse niet af te leiden van DependencyObject. Maar u moet wel afleiden van DependencyObject als u het algehele WPF-model volgt om uw gekoppelde eigenschap ook een afhankelijkheidseigenschap te laten zijn.

Definieer de gekoppelde eigenschap als een afhankelijkheidseigenschap door een public static readonly veld van het type DependencyPropertyte declareren. U definieert dit veld met behulp van de retourwaarde van de methode RegisterAttached. De veldnaam moet overeenkomen met de naam van de gekoppelde eigenschap, toegevoegd aan de tekenreeks Property, om het tot stand gebrachte WPF-patroon te volgen van de naamgeving van de identificatievelden versus de eigenschappen die ze vertegenwoordigen. De gekoppelde eigenschapsprovider moet ook statische GetPropertyName en SetPropertyName methoden als toegangsmethoden voor de gekoppelde eigenschap verschaffen; als u dit niet doet, kan het eigenschapssysteem uw gekoppelde eigenschap niet gebruiken.

Notitie

Als u de get-accessor van de gekoppelde eigenschap weglaat, werkt de gegevensbinding op de eigenschap niet in ontwerphulpprogramma's, zoals Visual Studio en Blend voor Visual Studio.

De Get Accessor

De signatuur voor de GetPropertyName accessor moet zijn:

public static object GetPropertyName(object target)

  • Het target-object kan worden opgegeven als een specifieker type in uw implementatie. De methode DockPanel.GetDock typt bijvoorbeeld de parameter als UIElement, omdat de gekoppelde eigenschap alleen is bedoeld voor UIElement exemplaren.

  • De retourwaarde kan worden opgegeven als een specifieker type in uw implementatie. De GetDock methode typt deze bijvoorbeeld als Dock, omdat de waarde alleen op die opsomming kan worden ingesteld.

De toegangsbeheerset

De handtekening voor de SetPropertyName accessor moet zijn:

public static void SetPropertyName(object target, object value)

  • Het target-object kan worden opgegeven als een specifieker type in uw implementatie. De methode SetDock typt deze bijvoorbeeld als UIElement, omdat de gekoppelde eigenschap alleen is bedoeld voor UIElement exemplaren.

  • Het value-object kan worden opgegeven als een specifieker type in uw implementatie. De SetDock methode typt deze bijvoorbeeld als Dock, omdat de waarde alleen op die opsomming kan worden ingesteld. Houd er rekening mee dat de waarde voor deze methode de invoer is die afkomstig is van het XAML-laadprogramma wanneer deze uw gekoppelde eigenschap tegenkomt in een gebruik van gekoppelde eigenschappen in markeringen. Deze invoer is de waarde die is opgegeven als een XAML-kenmerkwaarde in markeringen. Daarom moet er ondersteuning zijn voor typeconversie, waardeserialisatie of markeringsuitbreiding voor het type dat u gebruikt, zodat het juiste type kan worden gemaakt op basis van de kenmerkwaarde (wat uiteindelijk slechts een tekenreeks is).

In het volgende voorbeeld ziet u de registratie van de afhankelijkheidseigenschap (met behulp van de methode RegisterAttached), evenals de GetPropertyName en SetPropertyName toegangsmethoden. In het voorbeeld is de naam van de gekoppelde eigenschap IsBubbleSource. Daarom moeten de accessoren GetIsBubbleSource en SetIsBubbleSourcegenaamd worden.

public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
  "IsBubbleSource",
  typeof(Boolean),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
);
public static void SetIsBubbleSource(UIElement element, Boolean value)
{
  element.SetValue(IsBubbleSourceProperty, value);
}
public static Boolean GetIsBubbleSource(UIElement element)
{
  return (Boolean)element.GetValue(IsBubbleSourceProperty);
}
Public Shared ReadOnly IsBubbleSourceProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsBubbleSource", GetType(Boolean), GetType(AquariumObject), New FrameworkPropertyMetadata(False, FrameworkPropertyMetadataOptions.AffectsRender))
Public Shared Sub SetIsBubbleSource(ByVal element As UIElement, ByVal value As Boolean)
    element.SetValue(IsBubbleSourceProperty, value)
End Sub
Public Shared Function GetIsBubbleSource(ByVal element As UIElement) As Boolean
    Return CType(element.GetValue(IsBubbleSourceProperty), Boolean)
End Function

Gekoppelde eigenschapskenmerken

WPF definieert verschillende .NET-kenmerken die bedoeld zijn om informatie te verstrekken over gekoppelde eigenschappen voor reflectieprocessen en voor typische gebruikers van reflectie- en eigenschapsgegevens zoals ontwerpers. Omdat gekoppelde eigenschappen een onbeperkt bereik hebben, hebben ontwerpers een manier nodig om overweldigende gebruikers te voorkomen met een algemene lijst met alle gekoppelde eigenschappen die zijn gedefinieerd in een bepaalde technologie-implementatie die gebruikmaakt van XAML. De .NET-kenmerken die door WPF worden gedefinieerd voor gekoppelde eigenschappen, kunnen worden gebruikt om de situaties te bepalen waarin een bepaalde gekoppelde eigenschap moet worden weergegeven in een eigenschappenvenster. U kunt deze kenmerken ook toepassen voor uw eigen aangepaste gekoppelde eigenschappen. Het doel en de syntaxis van de .NET-kenmerken worden beschreven op de juiste referentiepagina's:

Meer informatie over gekoppelde eigenschappen

  • Zie Een gekoppelde eigenschap registrerenvoor meer informatie over het maken van een gekoppelde eigenschap.

  • Zie Aangepaste eigenschappen van afhankelijkhedenvoor meer geavanceerde gebruiksscenario's voor afhankelijkheidseigenschappen en gekoppelde eigenschappen.

  • U kunt ook een eigenschap registreren als een gekoppelde eigenschap en als een afhankelijkheidseigenschap, maar vervolgens nog steeds wrapper-implementaties beschikbaar maken. In dit geval kan de eigenschap worden ingesteld op dat specifieke element of op een willekeurig element via de gekoppelde XAML-eigenschapssyntaxis. Een voorbeeld van een eigenschap met een geschikt scenario voor zowel standaardgebruik als gekoppelde gebruiksbewerkingen is FrameworkElement.FlowDirection.

Zie ook