Sök…


Introduktion

Beroendeegenskaper är en typ av egendom som utvidgar en CLR-egenskap. Medan en CLR-egenskap läses direkt från en medlem i din klass, kommer en beroendeegenskap att lösas dynamiskt när du kallar GetValue () -metoden som ditt objekt får via arv från basen DependencyObject-klassen.

Detta avsnitt kommer att dela upp beroendeegenskaper och förklara deras användning både konceptuellt och genom kodexempel.

Syntax

  • DependencyProperty.Register (strängnamn, Type propertyType, Type ownerType)
  • DependencyProperty.Register (strängnamn, Type propertyType, Type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.Register (strängenamn, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)
  • DependencyProperty.RegisterAttached (strängnamn, Type propertyType, Type ownerType)
  • DependencyProperty.RegisterAttached (strängnamn, Type propertyType, Type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.RegisterAttached (strängnamn, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)
  • DependencyProperty.RegisterReadOnly (strängenamn, Type propertyType, Type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.RegisterReadOnly (strängenamn, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)
  • DependencyProperty.RegisterAttachedReadOnly (strängnamn, Type propertyType, Type ownerType, PropertyMetadata typeMetadata)
  • DependencyProperty.RegisterAttachedReadOnly (strängnamn, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)

parametrar

Parameter detaljer
namn String av fastighetens namn
propertyType Egenskapens Type , t.ex. typeof(int)
ownerType Type av klass i vilken egenskapen definieras, t.ex. typeof(MyControl) eller typeof(MyAttachedProperties) .
typeMetadata Förekomst av System.Windows.PropertyMetadata (eller en av dess underklasser) som definierar standardvärden, egendom ändrade återuppringningar, FrameworkPropertyMetadata gör det möjligt att definiera bindningsalternativ som System.Windows.Data.BindingMode.TwoWay .
validateValueCallback Anpassad återuppringning som returnerar sant om fastighetens nya värde är giltigt, annars falskt.

Standard beroendeegenskaper

När du ska använda den

Praktiskt taget alla WPF-kontroller använder sig mycket av beroendeegenskaper. En beroendeegenskap möjliggör användning av många WPF-funktioner som inte är möjliga med enbart standard CLR-egenskaper, inklusive men inte begränsat till stöd för stilar, animationer, databindning, värdearv och ändringsmeddelanden.

TextBox.Text egenskapen är ett enkelt exempel på där en standardberoendeegenskap behövs. Här skulle databindning inte vara möjlig om Text var en standardegenskap för CLR.

<TextBox Text="{Binding FirstName}" />

Hur man definierar

Beroendeegenskaper kan endast definieras i klasser härrörande från DependencyObject , som FrameworkElement , Control , etc.

Ett av de snabbaste sätten att skapa en standardberoendeegenskap utan att behöva komma ihåg syntaxen är att använda "propdp" -avsnittet genom att skriva propdp och sedan trycka på Tab . Ett kodavsnitt kommer att infogas som sedan kan ändras för att passa dina behov:

public class MyControl : Control
{
    public int MyProperty
    {
        get { return (int)GetValue(MyPropertyProperty); }
        set { SetValue(MyPropertyProperty, value); }
    }

    // Using a DependencyProperty as the backing store for MyProperty.
    // This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.Register("MyProperty", typeof(int), typeof(MyControl),
            new PropertyMetadata(0));
}

Du bör Tab genom de olika delarna av koden utdrag att göra nödvändiga förändringar, inklusive uppdatera egenskapsnamn, fastighetstyp, som innehåller klass typ, och standardvärdet.

Viktiga konventioner

Det finns några viktiga konventioner / regler att följa här:

  1. Skapa en CLR-egenskap för beroendeegenskapen. Den här egenskapen används i ditt objekts kod bakom eller av andra konsumenter. Det bör åberopa GetValue och SetValue så att konsumenter inte behöver göra det.

  2. Namnge beroendeegenskapen korrekt. Fältet DependencyProperty ska vara public static readonly . Det bör ha ett namn som motsvarar CLR-egenskapens namn och slutar med "Egenskap", t.ex. Text och TextProperty .

  3. Lägg inte till ytterligare logik till CLR-fastighetens uppsättare. Systemet för beroendeegenskaper (och XAML specifikt) använder inte CLR-egenskapen. Om du vill utföra en åtgärd när fastighetens värde ändras måste du lämna ett återuppringning via PropertyMetadata :

    public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.Register("MyProperty", typeof(int), typeof(MyControl),
            new PropertyMetadata(0, MyPropertyChangedHandler));
    
    private static void MyPropertyChangedHandler(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        // Use args.OldValue and args.NewValue here as needed.
        // sender is the object whose property changed.
        // Some unboxing required.
    }
    

Bindningsläge

För att eliminera behovet av att ange Mode=TwoWay i bindningar (i likhet med beteendet hos TextBox.Text ) uppdatera koden för att använda FrameworkPropertyMetadata istället för PropertyMetadata och ange lämplig flagga:

public static readonly DependencyProperty MyPropertyProperty =
    DependencyProperty.Register("MyProperty", typeof(int), typeof(MyControl), 
        new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

Bifogade beroendeegenskaper

När du ska använda den

En bifogad egenskap är en beroendeegenskap som kan tillämpas på alla DependencyObject att förbättra beteendet hos olika kontroller eller tjänster som är medvetna om fastighetens existens.

Vissa användningsfall för bifogade egenskaper inkluderar:

  1. Att ha ett förälderelement iterera genom sina barn och agera på barnen på ett visst sätt. Grid kontrollen använder till exempel Grid.Row , Grid.Column , Grid.RowSpan och Grid.ColumnSpan att ordna element i rader och kolumner.
  2. Lägga till visuella bilder till befintliga kontroller med anpassade mallar, t.ex. lägga till vattenmärken i tomma textrutor i hela appen utan att behöva underklassera TextBox .
  3. Tillhandahålla en generisk tjänst eller funktion till några eller alla befintliga kontroller, t.ex. ToolTipService eller FocusManager . Dessa kallas ofta bifogade beteenden .
  4. När det är nödvändigt att gå ner i det visuella trädet, t ex liknar beteendet hos DataContext .

Detta visar vidare vad som händer i Grid användningsfallet:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <Label Grid.Column="0" Content="Your Name:" />
    <TextBox Grid.Column="1" Text="{Binding FirstName}" />
</Grid>

Grid.Column är inte en egenskap som finns på varken Label eller TextBox . Snarare ser Grid kontrollen igenom sina barnelement och ordnar dem enligt värdena på de bifogade egenskaperna.

Hur man definierar

Vi fortsätter att använda Grid för det här exemplet. Definitionen av Grid.Column visas nedan, men DependencyPropertyChangedEventHandler är utesluten för korthet.

public static readonly DependencyProperty RowProperty =
    DependencyProperty.RegisterAttached("Row", typeof(int), typeof(Grid),
        new FrameworkPropertyMetadata(0, ...));

public static void SetRow(UIElement element, int value)
{
    if (element == null)
        throw new ArgumentNullException("element");

    element.SetValue(RowProperty, value);
}

public static int GetRow(UIElement element)
{
    if (element == null)
        throw new ArgumentNullException("element");

    return ((int)element.GetValue(RowProperty));
}

Eftersom de bifogade egenskaperna kan kopplas till en mängd olika objekt kan de inte implementeras som CLR-egenskaper. I stället introduceras ett par statiska metoder.

Till skillnad från standardberoendeegenskaper kan bifogade egenskaper också definieras i klasser som inte härleds från DependencyObject .

Samma namngivningskonventioner som gäller för vanliga beroendeegenskaper gäller också här: beroendeegenskapen RowProperty har motsvarande metoder GetRow och SetRow .

förbehåll

Som dokumenterat på MSDN :

Även om egendomens arv kan tyckas fungera för icke-kopplade beroendeegenskaper, är arvsbeteendet för en icke-kopplad egendom genom vissa elementgränser i körtidsträdet odefinierat. Använd alltid RegisterAttached för att registrera egenskaper där du anger arv i metadata.

Beroende på beroendeegenskaper

När du ska använda den

En läsbar beroendeegenskap liknar en normal beroendeegenskap, men den är strukturerad för att inte tillåta att dess värde ställs in utanför kontrollen. Det här fungerar bra om du har en egendom som är rent informativ för konsumenter, t.ex. IsMouseOver eller IsKeyboardFocusWithin .

Hur man definierar

Precis som standardberoendeegenskaper måste en läsbar beroendeegenskap definieras i en klass som härrör från DependencyObject .

public class MyControl : Control
{
    private static readonly DependencyPropertyKey MyPropertyPropertyKey = 
        DependencyProperty.RegisterReadOnly("MyProperty", typeof(int), typeof(MyControl),
            new FrameworkPropertyMetadata(0));

    public static readonly DependencyProperty MyPropertyProperty = MyPropertyPropertyKey.DependencyProperty;

    public int MyProperty
    {
        get { return (int)GetValue(MyPropertyProperty); }
        private set { SetValue(MyPropertyPropertyKey, value); }
    }
}

Samma konventioner som gäller för vanliga beroendeegenskaper gäller också här, men med två viktiga skillnader:

  1. DependencyProperty kommer från en private DependencyPropertyKey .
  2. CLR-fastighetsskyddet är protected eller private istället för public .

Observera att setern skickar MyPropertyPropertyKey och inte MyPropertyProperty till SetValue metoden. Eftersom egenskapen definierades som skrivskyddad måste alla försök att använda SetValue på egenskapen användas med överbelastning som får DependencyPropertyKey ; annars InvalidOperationException en InvalidOperationException .



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow