Delen via


Overname van eigenschapswaarden (WPF .NET)

Overname van eigenschapswaarden is een functie van het WPF-eigenschappensysteem (Windows Presentation Foundation) en is van toepassing op afhankelijkheidseigenschappen. Met eigenschapswaardeovername kunnen onderliggende elementen in een structuur met elementen de waarde van een bepaalde eigenschap verkrijgen van het dichtstbijzijnde bovenliggende element. Omdat een bovenliggend element mogelijk ook de eigenschapswaarde heeft verkregen via eigenschapswaardenovererving, kan het systeem mogelijk terugkeren naar de wortel van de pagina.

Het WPF-eigenschappensysteem schakelt de overname van eigenschapswaarden standaard niet in, en waardeovername is inactief, tenzij specifiek ingeschakeld in de metadata van de afhankelijkheidseigenschap . Zelfs als de overerving van eigenschapswaarden is ingeschakeld, neemt een onderliggend element een eigenschapswaarde alleen over bij afwezigheid van een hogere prioriteit waarde.

Voorwaarden

In het artikel wordt ervan uitgegaan dat u basiskennis hebt van afhankelijkheidseigenschappen en dat u overzicht van eigenschappen van afhankelijkheden hebt gelezen. Als u de voorbeelden in dit artikel wilt volgen, helpt dit als u bekend bent met Extensible Application Markup Language (XAML) en weet hoe u WPF-toepassingen schrijft.

Overname via een elementstructuur

Overname van eigenschapswaarden is niet hetzelfde concept als klasseovername in objectgeoriënteerde programmering, waarbij afgeleide klassen basisklasseleden overnemen. Dit soort overname is ook actief in WPF, hoewel in XAML de overgenomen basisklasse-eigenschappen worden weergegeven als kenmerken van XAML-elementen die afgeleide klassen vertegenwoordigen.

Overname van eigenschapswaarden is het mechanisme waarmee een eigenschapswaarde van een afhankelijkheid wordt doorgegeven van bovenliggende naar onderliggende elementen in een structuur met elementen die de eigenschap bevatten. In XAML-markup is een boom van elementen zichtbaar als geneste elementen.

In het volgende voorbeeld ziet u geneste elementen in XAML. WPF registreert de eigenschap AllowDrop afhankelijkheid van de UIElement klasse met eigenschap metagegevens die eigenschapswaarde overname mogelijk maakt en de standaardwaarde instelt op false. De eigenschap AllowDrop afhankelijkheid bestaat op Canvas, StackPanelen Label elementen, omdat ze allemaal zijn afgeleid van UIElement. Omdat de afhankelijkheidseigenschap AllowDrop van canvas1 is ingesteld op true, erven de onderliggende stackPanel1- en label1-elementen true als hun AllowDrop-waarde.

<Canvas x:Name="canvas1" Grid.Column="0" Margin="20" Background="Orange" AllowDrop="True">
    <StackPanel Name="stackPanel1" Margin="20" Background="Green">
        <Label Name="label1" Margin="20" Height="40" Width="40" Background="Blue"/>
    </StackPanel>
</Canvas>

U kunt ook programmatisch een structuur met elementen maken door elementobjecten toe te voegen aan de verzameling onderliggende elementen van een ander elementobject. Tijdens runtime werkt de overname van eigenschapswaarden op de resulterende objectstructuur. In het volgende voorbeeld wordt stackPanel2 toegevoegd aan de kindcollectie van canvas2. Op dezelfde manier wordt label2 toegevoegd aan de subverzameling van stackPanel2. Aangezien de afhankelijkheidseigenschap AllowDrop van canvas2 is ingesteld op true, erven de onderliggende elementen stackPanel2 en label2true als hun AllowDrop-waarde.

Canvas canvas2 = new()
{
    AllowDrop = true
};
StackPanel stackPanel2 = new();
Label label2 = new();
canvas2.Children.Add(stackPanel2);
stackPanel2.Children.Add(label2);
Dim canvas2 As New Canvas With {
    .AllowDrop = True
}
Dim stackPanel2 As New StackPanel()
Dim label2 As New Label()
canvas2.Children.Add(stackPanel2)
stackPanel2.Children.Add(label2)

Praktische toepassingen van overname van eigenschapswaarde

Specifieke WPF-afhankelijkheidseigenschappen hebben standaard waardeovername ingeschakeld, zoals AllowDrop en FlowDirection. Eigenschappen waarvoor de overname van waarden standaard is ingeschakeld, worden doorgaans geïmplementeerd op basis-UI-elementklassen, zodat ze bestaan op afgeleide klassen. Omdat AllowDrop bijvoorbeeld is geïmplementeerd op de UIElement basisklasse, bestaat die afhankelijkheidseigenschap ook voor elk besturingselement dat is afgeleid van UIElement. WPF maakt overname van waarden mogelijk op afhankelijkheidseigenschappen waarvoor een gebruiker de eigenschapswaarde eenmaal op een bovenliggend element kan instellen en die eigenschapswaarde doorgeeft aan onderliggende elementen in de elementstructuur.

Het overnamemodel voor eigenschapswaarden wijst eigenschapswaarden toe, zowel overgenomen als niet-overgenomen, volgens voorrang van de afhankelijkheidseigenschapswaarde. Een eigenschapswaarde van een bovenliggend element wordt dus alleen toegepast op een onderliggend element, als de eigenschap van het onderliggende element geen hogere prioriteitswaarde heeft, zoals een lokaal ingestelde waarde of een waarde die is verkregen via stijlen, sjablonen of gegevensbinding.

De afhankelijkheidseigenschap FlowDirection stelt de indelingsrichting in van tekst en kind-UI-elementen binnen een bovenliggend element. Normaal gesproken verwacht u dat de richting van de tekst en gebruikersinterface-elementen op een pagina consistent is. Omdat overname van waarden is ingeschakeld in de eigenschap metagegevens van FlowDirection, hoeft een waarde slechts één keer boven aan de elementstructuur voor een pagina te worden ingesteld. In zeldzame gevallen waarin een combinatie van stroomrichtingen is bedoeld voor een pagina, kan een andere stroomrichting worden ingesteld op een element in de structuur door een lokaal ingestelde waarde toe te wijzen. De nieuwe stroomrichting wordt vervolgens doorgegeven aan onderliggende elementen onder dat niveau.

Een aangepaste eigenschap overnemend maken

U kunt een aangepaste afhankelijkheidseigenschap overnemen door de eigenschap Inherits in te schakelen in een exemplaar van FrameworkPropertyMetadataen vervolgens uw aangepaste afhankelijkheidseigenschap te registreren bij dat metagegevensexemplaren. Standaard is Inherits ingesteld op false in FrameworkPropertyMetadata. Het overnemen van een eigenschapswaarde is van invloed op de prestaties, dus stel Inherits in op true als deze functie nodig is.

Wanneer u een afhankelijkheidseigenschap registreert met Inherits ingeschakeld in metagegevens, gebruikt u de methode RegisterAttached zoals beschreven in Een gekoppelde eigenschap registreren. Wijs ook een standaardwaarde toe aan de eigenschap, zodat er een overgenomen waarde bestaat. U kunt ook een eigenschapswrapper maken met get en set toegangspunten op het eigenaartype, net zoals u zou doen voor een niet-verbonden afhankelijke eigenschap. Op die manier kunt u de eigenschapswaarde instellen met behulp van de eigenschapswikkelaar voor een eigenaar of afgeleid type. In het volgende voorbeeld wordt een afhankelijkheidseigenschap met de naam IsTransparentgemaakt, met Inherits ingeschakeld en een standaardwaarde van false. Het voorbeeld bevat ook een eigenschap wikkelaar met get- en set-accessors.

public class Canvas_IsTransparentInheritEnabled : Canvas
{
    // Register an attached dependency property with the specified
    // property name, property type, owner type, and property metadata
    // (default value is 'false' and property value inheritance is enabled).
    public static readonly DependencyProperty IsTransparentProperty =
        DependencyProperty.RegisterAttached(
            name: "IsTransparent",
            propertyType: typeof(bool),
            ownerType: typeof(Canvas_IsTransparentInheritEnabled),
            defaultMetadata: new FrameworkPropertyMetadata(
                defaultValue: false,
                flags: FrameworkPropertyMetadataOptions.Inherits));

    // Declare a get accessor method.
    public static bool GetIsTransparent(Canvas element)
    {
        return (bool)element.GetValue(IsTransparentProperty);
    }

    // Declare a set accessor method.
    public static void SetIsTransparent(Canvas element, bool value)
    {
        element.SetValue(IsTransparentProperty, value);
    }

    // For convenience, declare a property wrapper with get/set accessors.
    public bool IsTransparent
    {
        get => (bool)GetValue(IsTransparentProperty);
        set => SetValue(IsTransparentProperty, value);
    }
}
Public Class Canvas_IsTransparentInheritEnabled
    Inherits Canvas

    ' Register an attached dependency property with the specified
    ' property name, property type, owner type, and property metadata
    ' (default value is 'false' and property value inheritance is enabled).
    Public Shared ReadOnly IsTransparentProperty As DependencyProperty =
        DependencyProperty.RegisterAttached(
            name:="IsTransparent",
            propertyType:=GetType(Boolean),
            ownerType:=GetType(Canvas_IsTransparentInheritEnabled),
            defaultMetadata:=New FrameworkPropertyMetadata(
                defaultValue:=False,
                flags:=FrameworkPropertyMetadataOptions.[Inherits]))

    ' Declare a get accessor method.
    Public Shared Function GetIsTransparent(element As Canvas) As Boolean
        Return element.GetValue(IsTransparentProperty)
    End Function

    ' Declare a set accessor method.
    Public Shared Sub SetIsTransparent(element As Canvas, value As Boolean)
        element.SetValue(IsTransparentProperty, value)
    End Sub

    ' For convenience, declare a property wrapper with get/set accessors.
    Public Property IsTransparent As Boolean
        Get
            Return GetValue(IsTransparentProperty)
        End Get
        Set(value As Boolean)
            SetValue(IsTransparentProperty, value)
        End Set
    End Property
End Class

Gekoppelde eigenschappen zijn conceptueel vergelijkbaar met globale eigenschappen. U kunt de waarde controleren op elke DependencyObject en een geldig resultaat krijgen. Het typische scenario voor gekoppelde eigenschappen is het instellen van eigenschapswaarden voor onderliggende elementen en dat scenario is effectiever als de betreffende eigenschap impliciet aanwezig is als een gekoppelde eigenschap op elk DependencyObject element in de structuur.

Eigenschapswaarden overnemen over de structuurgrenzen

De erfelijkheid van eigenschappen werkt door het doorlopen van een elementstructuur. Deze structuur is vaak parallel aan de logische structuur. Wanneer u echter een WPF-kernobject, zoals een Brush, opneemt in de markering die een elementstructuur definieert, hebt u een niet-aaneenlopende logische structuur gemaakt. Een echte logische structuur wordt niet conceptueel uitgebreid via de Brush, omdat de logische structuur een concept op WPF-frameworkniveau is. U kunt de helpermethoden van LogicalTreeHelper gebruiken om de omvang van een logische structuur te analyseren en te bekijken. Overname van eigenschapswaarden kan overgenomen waarden doorgeven via een niet-aaneengesloten logische structuur, maar alleen als de overgenomen eigenschap is geregistreerd als een gekoppelde eigenschap en er geen opzettelijke overnameblokkeringsgrens is, zoals een Frame.

Notitie

Hoewel overname van eigenschapswaarden kan werken voor niet-gekoppelde afhankelijkheidseigenschappen, is het overnamegedrag voor een niet-gekoppelde eigenschap via bepaalde elementgrenzen in de runtimestructuur niet gedefinieerd. Wanneer u Inherits opgeeft in metagegevens van eigenschappen, registreert u uw eigenschappen met behulp van RegisterAttached.

Zie ook