wpf
Beroendeegenskaper
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:
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
ochSetValue
så att konsumenter inte behöver göra det.Namnge beroendeegenskapen korrekt. Fältet
DependencyProperty
ska varapublic static readonly
. Det bör ha ett namn som motsvarar CLR-egenskapens namn och slutar med "Egenskap", t.ex.Text
ochTextProperty
.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:
- Att ha ett förälderelement iterera genom sina barn och agera på barnen på ett visst sätt.
Grid
kontrollen använder till exempelGrid.Row
,Grid.Column
,Grid.RowSpan
ochGrid.ColumnSpan
att ordna element i rader och kolumner. - 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
. - Tillhandahålla en generisk tjänst eller funktion till några eller alla befintliga kontroller, t.ex.
ToolTipService
ellerFocusManager
. Dessa kallas ofta bifogade beteenden . - 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:
-
DependencyProperty
kommer från enprivate
DependencyPropertyKey
. - CLR-fastighetsskyddet är
protected
ellerprivate
istället förpublic
.
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
.