Načítání XAML a vlastnosti závislostí (WPF .NET)

Implementace windows Presentation Foundation (WPF) procesoru XAML (Extensible Application Markup Language) je ze své podstaty závislé vlastnosti. Procesor XAML používá metody systému vlastností WPF k načtení atributů vlastností XAML a zpracování závislostí a zcela obchází obálky vlastností závislostí pomocí metod systému vlastností WPF jako GetValue a SetValue. Pokud tedy do obálky vlastnosti vlastní závislosti přidáte vlastní logiku, procesor XAML ji nebude volat, pokud je hodnota vlastnosti nastavena v JAZYCE XAML.

Důležité

Dokumentace k desktopové příručce pro .NET 7 a .NET 6 se právě připravuje.

Předpoklady

V článku se předpokládá základní znalost vlastností závislostí a že jste si přečetli přehled vlastností závislostí. Pokud chcete postupovat podle příkladů v tomto článku, pomůže vám to, pokud znáte jazyk XAML (Extensible Application Markup Language) a víte, jak psát aplikace WPF.

Výkon zavaděče WPF XAML

Procesor WPF XAML je výpočetně levnější, aby přímo volal SetValue , aby nastavil hodnotu vlastnosti závislosti místo použití obálky vlastnosti závislosti.

Pokud procesor XAML použil obálku vlastnosti, vyžadoval by odvození celého objektového modelu backing kódu na základě vztahů typu a členů uvedených v revizích. I když lze typ identifikovat z revizí pomocí kombinace xmlns atributů a sestavení, identifikace členů, určení, které členy lze nastavit jako atribut a přeložit podporované typy hodnot vlastností, by vyžadovalo rozsáhlé reflexe pomocí PropertyInfo.

Systém vlastností WPF udržuje tabulku úložišť vlastností závislostí implementovaných pro daný DependencyObject odvozený typ. Procesor XAML používá danou tabulku k odvození identifikátoru vlastnosti závislosti pro vlastnost závislosti. Například podle konvence identifikátor vlastnosti závislosti pro vlastnost závislost s názvem ABC .ABCProperty Procesor XAML může efektivně nastavit hodnotu jakékoli vlastnosti závislosti voláním SetValue metody na jeho obsahující typ pomocí identifikátoru vlastnosti závislosti.

Další informace o obálkách vlastností závislostí naleznete v tématu Vlastní vlastnosti závislostí.

Důsledky pro vlastní vlastnosti závislostí

Procesor WPF XAML obchází obálky vlastností a přímo volá SetValue nastavení hodnoty vlastnosti závislosti. Proto se vyhněte vložení jakékoli další logiky do set přistupovacího objektu vlastní vlastnosti závislosti, protože tato logika se nespustí při nastavení hodnoty vlastnosti v XAML. Příslušenství set by mělo obsahovat SetValue pouze volání.

Podobně aspekty procesoru WPF XAML, které získávají hodnoty vlastností obejít obálku vlastnosti a přímo volat GetValue. Proto se také vyhněte vložení jakékoli další logiky do get přistupovacího objektu vlastní vlastnosti závislosti, protože tato logika se nespustí při čtení hodnoty vlastnosti v XAML. Příslušenství get by mělo obsahovat GetValue pouze volání.

Vlastnost závislostí s příkladem obálky

Následující příklad ukazuje doporučenou definici vlastnosti závislostí s obálkami vlastností. Identifikátor vlastnosti závislosti je uložen jako public static readonly pole a get přístupové set objekty neobsahují žádný kód nad rámec nezbytných metod systému vlastností WPF, které zpět hodnotu vlastnosti závislosti. Pokud máte kód, který se musí spustit, když se změní hodnota vlastnosti závislosti, zvažte vložení tohoto kódu do PropertyChangedCallback vlastnosti závislosti. Další informace naleznete v tématu Zpětná volání změněná vlastností.

// Register a dependency property with the specified property name,
// property type, owner type, and property metadata. Store the dependency
// property identifier as a public static readonly member of the class.
public static readonly DependencyProperty AquariumGraphicProperty =
    DependencyProperty.Register(
      name: "AquariumGraphic",
      propertyType: typeof(Uri),
      ownerType: typeof(Aquarium),
      typeMetadata: new FrameworkPropertyMetadata(
          defaultValue: new Uri("http://www.contoso.com/aquarium-graphic.jpg"),
          flags: FrameworkPropertyMetadataOptions.AffectsRender,
          propertyChangedCallback: new PropertyChangedCallback(OnUriChanged))
    );

// Property wrapper with get & set accessors.
public Uri AquariumGraphic
{
    get => (Uri)GetValue(AquariumGraphicProperty);
    set => SetValue(AquariumGraphicProperty, value);
}

// Property-changed callback.
private static void OnUriChanged(DependencyObject dependencyObject, 
    DependencyPropertyChangedEventArgs e)
{
    // Some custom logic that runs on effective property value change.
    Uri newValue = (Uri)dependencyObject.GetValue(AquariumGraphicProperty);
    Debug.WriteLine($"OnUriChanged: {newValue}");
}
' Register a dependency property with the specified property name,
' property type, owner type, and property metadata. Store the dependency
' property identifier as a public static readonly member of the class.
Public Shared ReadOnly AquariumGraphicProperty As DependencyProperty =
    DependencyProperty.Register(
        name:="AquariumGraphic",
        propertyType:=GetType(Uri),
        ownerType:=GetType(Aquarium),
        typeMetadata:=New FrameworkPropertyMetadata(
            defaultValue:=New Uri("http://www.contoso.com/aquarium-graphic.jpg"),
            flags:=FrameworkPropertyMetadataOptions.AffectsRender,
            propertyChangedCallback:=New PropertyChangedCallback(AddressOf OnUriChanged)))

' Property wrapper with get & set accessors.
Public Property AquariumGraphic As Uri
    Get
        Return CType(GetValue(AquariumGraphicProperty), Uri)
    End Get
    Set
        SetValue(AquariumGraphicProperty, Value)
    End Set
End Property

' Property-changed callback.
Private Shared Sub OnUriChanged(dependencyObject As DependencyObject,
                                e As DependencyPropertyChangedEventArgs)
    ' Some custom logic that runs on effective property value change.
    Dim newValue As Uri = CType(dependencyObject.GetValue(AquariumGraphicProperty), Uri)
    Debug.WriteLine($"OnUriChanged: {newValue}")
End Sub

Viz také