Omówienie dołączonych właściwości (WPF .NET)

Dołączona właściwość to koncepcja języka XAML (Extensible Application Markup Language). Dołączone właściwości umożliwiają ustawienie dodatkowych par właściwości/wartości dla dowolnego elementu XAML pochodzącego z DependencyObjectklasy , mimo że element nie definiuje tych dodatkowych właściwości w modelu obiektów. Dodatkowe właściwości są dostępne globalnie. Dołączone właściwości są zwykle definiowane jako wyspecjalizowana forma właściwości zależności, która nie ma konwencjonalnej otoki właściwości.

Ważne

Dokumentacja przewodnika dla komputerów dla platform .NET 7 i .NET 6 jest w budowie.

Wymagania wstępne

W tym artykule przyjęto założenie, że masz podstawową wiedzę na temat właściwości zależności i zapoznasz się z omówieniem właściwości zależności. Aby postępować zgodnie z przykładami w tym artykule, warto zapoznać się z językiem XAML i wiedzieć, jak pisać aplikacje programu Windows Presentation Foundation (WPF).

Dlaczego warto używać dołączonych właściwości

Dołączona właściwość umożliwia elementowi podrzędnym określenie unikatowej wartości właściwości zdefiniowanej w elemecie nadrzędnym. Typowym scenariuszem jest element podrzędny określający sposób renderowania go w interfejsie użytkownika przez jego element nadrzędny. Na przykład jest to właściwość dołączona, DockPanel.Dock ponieważ jest ustawiona na elementy DockPanelpodrzędne elementu , a nie DockPanel samego. Klasa DockPanel definiuje pole statyczne DependencyProperty o nazwie DockProperty, a następnie udostępnia GetDock metody i SetDock jako publiczne metody dostępu dla dołączonej właściwości.

Dołączone właściwości w języku XAML

W języku XAML ustawiasz dołączone właściwości przy użyciu składni <attached property provider type>.<property name>, gdzie dołączony dostawca właściwości jest klasą definiującą dołączoną właściwość. W poniższym przykładzie pokazano, jak element podrzędny DockPanel elementu może ustawić DockPanel.Dock wartość właściwości.

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

Użycie jest podobne do właściwości statycznej, w której odwołuje się typ, który jest właścicielem i rejestruje dołączoną właściwość (na przykład DockPanel), a nie nazwę wystąpienia.

Po określeniu dołączonej właściwości przy użyciu atrybutu XAML ma zastosowanie tylko akcja zestawu. Nie można bezpośrednio uzyskać wartości właściwości za pomocą języka XAML, chociaż istnieją pewne mechanizmy pośrednie do porównywania wartości, takich jak wyzwalacze w stylach.

Dołączone właściwości w WPF

Dołączone właściwości są koncepcją XAML, właściwości zależności są koncepcją WPF. W WPF większość właściwości dołączonych interfejsu użytkownika w typach WPF jest implementowana jako właściwości zależności. Właściwości dołączone WPF, które są implementowane jako właściwości zależności obsługują koncepcje właściwości zależności, takie jak metadane właściwości, w tym wartości domyślne z metadanych.

Dołączone modele użycia właściwości

Mimo że dowolny obiekt może ustawić dołączoną wartość właściwości, nie oznacza to ustawienia wartości spowoduje wygenerowanie namacalnego wyniku lub wartość będzie używana przez inny obiekt. Głównym celem dołączonych właściwości jest zapewnienie sposobu na obiekty z szerokiej gamy hierarchii klas i relacji logicznych w celu zgłaszania typowych informacji do typu definiującego dołączoną właściwość. Użycie dołączonych właściwości zwykle jest zgodne z jednym z następujących modeli:

  • Typ definiujący dołączoną właściwość jest elementem nadrzędnym elementów, które ustawiają wartości dla dołączonej właściwości. Typ nadrzędny iteruje swoje obiekty podrzędne za pomocą wewnętrznej logiki, która działa na strukturze drzewa obiektów, uzyskuje wartości i działa na tych wartościach w jakiś sposób.
  • Typ definiujący dołączoną właściwość jest używany jako element podrzędny dla różnych możliwych elementów nadrzędnych i con tryb namiotu ls.
  • Typ definiujący dołączoną właściwość reprezentuje usługę. Inne typy ustawiają wartości dla dołączonej właściwości. Następnie, gdy element, który ustawi właściwość jest obliczany w kontekście usługi, dołączone wartości właściwości są uzyskiwane za pomocą wewnętrznej logiki klasy usługi.

Przykład właściwości dołączonej zdefiniowanej przez element nadrzędny

Typowy scenariusz, w którym WPF definiuje dołączoną właściwość, jest wtedy, gdy element nadrzędny obsługuje kolekcję elementów podrzędnych, a element nadrzędny implementuje zachowanie na podstawie danych zgłaszanych przez poszczególne elementy podrzędne.

DockPanel definiuje dołączoną DockPanel.Dock właściwość. DockPanel ma kod na poziomie klasy, w szczególności MeasureOverride i ArrangeOverride, który jest częścią logiki renderowania. Wystąpienie DockPanel sprawdza, czy którykolwiek z jego natychmiastowych elementów podrzędnych ma ustawioną wartość .DockPanel.Dock Jeśli tak, te wartości stają się danymi wejściowymi logiki renderowania zastosowanej do każdego elementu podrzędnego. Mimo że teoretycznie możliwe jest, aby dołączone właściwości wpływały na elementy poza bezpośrednim elementem nadrzędnym, zdefiniowane zachowanie dla wystąpienia zagnieżdżonego DockPanel polega tylko na interakcji z bezpośrednią kolekcją elementów podrzędnych. Dlatego jeśli ustawisz DockPanel.Dock dla elementu, który nie DockPanel ma elementu nadrzędnego, nie zostanie zgłoszony błąd lub wyjątek i zostanie utworzona wartość właściwości globalnej, która nie zostanie zużyta przez żaden DockPanelelement .

Dołączone właściwości w kodzie

Dołączone właściwości w WPF nie mają typowych metod CLR get i set otoki, ponieważ właściwości mogą być ustawione spoza przestrzeni nazw CLR. Aby umożliwić procesorowi XAML ustawienie tych wartości podczas analizowania kodu XAML, klasa definiująca dołączoną właściwość musi implementować dedykowane metody dostępu w postaci Get<property name> i Set<property name>.

Możesz również użyć dedykowanych metod dostępu, aby uzyskać i ustawić dołączoną właściwość w kodzie, jak pokazano w poniższym przykładzie. W tym przykładzie myTextBox jest wystąpieniem TextBox klasy .

DockPanel myDockPanel = new();
TextBox myTextBox = new();
myTextBox.Text = "Enter text";

// Add child element to the DockPanel.
myDockPanel.Children.Add(myTextBox);

// Set the attached property value.
DockPanel.SetDock(myTextBox, Dock.Top);
Dim myDockPanel As DockPanel = New DockPanel()
Dim myTextBox As TextBox = New TextBox()
myTextBox.Text = "Enter text"

' Add child element to the DockPanel.
myDockPanel.Children.Add(myTextBox)

' Set the attached property value.
DockPanel.SetDock(myTextBox, Dock.Top)

Jeśli nie dodasz myTextBox go jako elementu podrzędnego , wywołanie SetDock nie zgłosi wyjątku myDockPanelani nie będzie miało żadnego wpływu. Tylko wartość ustawiona DockPanel.Dock dla elementu podrzędnego DockPanel elementu może mieć wpływ na renderowanie, a renderowanie będzie takie samo, czy ustawiono wartość przed, czy po dodaniu elementu podrzędnego DockPaneldo elementu .

Z perspektywy kodu dołączona właściwość jest jak pole zapasowe, które ma metody dostępu zamiast metod dostępu do właściwości, i można ustawić na dowolnym obiekcie bez uprzedniego zdefiniowania na tych obiektach.

Metadane dołączonej właściwości

Metadane dołączonej właściwości zwykle nie różnią się od właściwości zależności. Podczas rejestrowania dołączonej właściwości należy FrameworkPropertyMetadata określić cechy właściwości, takie jak wpływ właściwości na renderowanie lub pomiar. Po określeniu wartości domyślnej przez zastąpienie dołączonych metadanych właściwości ta staje się wartością domyślną niejawnej dołączonej właściwości w wystąpieniach klasy zastępowania. Jeśli wartość dołączonej właściwości nie jest ustawiona w inny sposób, wartość domyślna jest zgłaszana, gdy właściwość jest odpytywane przy użyciu Get<property name> metody dostępu z wystąpieniem klasy, w którym określono metadane.

Aby włączyć dziedziczenie wartości właściwości we właściwości, użyj dołączonych właściwości zamiast właściwości zależności, które nie są dołączone. Aby uzyskać więcej informacji, zobacz Dziedziczenie wartości właściwości.

Niestandardowe dołączone właściwości

Kiedy utworzyć dołączoną właściwość

Tworzenie dołączonej właściwości jest przydatne, gdy:

  • Potrzebny jest mechanizm ustawiania właściwości dostępny dla klas innych niż klasa definiująca. Typowym scenariuszem jest układ interfejsu użytkownika, na przykład DockPanel.Dock, Panel.ZIndexi Canvas.Top są przykładami istniejących właściwości układu. W scenariuszu układu elementy podrzędne elementu sterującego układem są w stanie wyrazić wymagania układu do ich elementu nadrzędnego układu i ustawić wartość dla dołączonej właściwości zdefiniowanej przez element nadrzędny.

  • Jedna z klas reprezentuje usługę i chcesz, aby inne klasy były bardziej przejrzyste.

  • Chcesz, aby program Visual Studio WPF Projektant obsługiwał, na przykład możliwość edytowania właściwości za pośrednictwem okna Właściwości. Aby uzyskać więcej informacji, zobacz Omówienie tworzenia kontrolek.

  • Chcesz użyć dziedziczenia wartości właściwości.

Jak utworzyć dołączoną właściwość

Jeśli klasa definiuje dołączoną właściwość wyłącznie do użytku przez inne typy, klasa nie musi pochodzić z klasy DependencyObject. W przeciwnym razie postępuj zgodnie z modelem WPF, aby mieć dołączoną właściwość również być właściwością zależności, wyprowadzając klasę z klasy .DependencyObject

Zdefiniuj dołączoną właściwość jako zależność w klasie definiującej, deklarując public static readonly pole typu DependencyProperty. Następnie przypisz wartość RegisterAttached zwracaną metody do pola, które jest również nazywane identyfikatorem właściwości zależności. Postępuj zgodnie z konwencją nazewnictwa właściwości WPF, która odróżnia pola od właściwości, które reprezentują, nazewając pole <property name>Propertyidentyfikatora . Ponadto podaj metody statyczne Get<property name> i Set<property name> metody dostępu, które umożliwiają systemowi właściwości dostęp do dołączonej właściwości.

W poniższym przykładzie pokazano, jak zarejestrować właściwość zależności przy użyciu RegisterAttached metody i jak zdefiniować metody dostępu. W tym przykładzie nazwa dołączonej właściwości to , więc pole identyfikatora ma HasFishnazwę HasFishProperty, a metody dostępu mają nazwy GetHasFish i SetHasFish.

public class Aquarium : UIElement
{
    // Register an attached dependency property with the specified
    // property name, property type, owner type, and property metadata.
    public static readonly DependencyProperty HasFishProperty = 
        DependencyProperty.RegisterAttached(
      "HasFish",
      typeof(bool),
      typeof(Aquarium),
      new FrameworkPropertyMetadata(defaultValue: false,
          flags: FrameworkPropertyMetadataOptions.AffectsRender)
    );

    // Declare a get accessor method.
    public static bool GetHasFish(UIElement target) =>
        (bool)target.GetValue(HasFishProperty);

    // Declare a set accessor method.
    public static void SetHasFish(UIElement target, bool value) =>
        target.SetValue(HasFishProperty, value);
}
Public Class Aquarium
    Inherits UIElement

    ' Register an attached dependency property with the specified
    ' property name, property type, owner type, and property metadata.
    Public Shared ReadOnly HasFishProperty As DependencyProperty =
        DependencyProperty.RegisterAttached("HasFish", GetType(Boolean), GetType(Aquarium),
            New FrameworkPropertyMetadata(defaultValue:=False,
                flags:=FrameworkPropertyMetadataOptions.AffectsRender))

    ' Declare a get accessor method.
    Public Shared Function GetHasFish(target As UIElement) As Boolean
        Return target.GetValue(HasFishProperty)
    End Function

    ' Declare a set accessor method.
    Public Shared Sub SetHasFish(target As UIElement, value As Boolean)
        target.SetValue(HasFishProperty, value)
    End Sub

End Class

Get accessor (Pobierz metodę dostępu)

Sygnatura get metody dostępu to public static object Get<property name>(DependencyObject target), gdzie:

  • target to właściwość DependencyObject , z której jest odczytywana dołączona właściwość. Typ target może być bardziej szczegółowy niż DependencyObject. Na przykład DockPanel.GetDock metoda dostępu wpisze metodę target jako, UIElement ponieważ dołączona właściwość ma zostać ustawiona na UIElement wystąpieniach. UiElement pośrednio pochodzi z klasy DependencyObject.
  • Typ zwracany może być bardziej szczegółowy niż object. Na przykład GetDock metoda wpisze zwróconą wartość jako Dock , ponieważ zwracana wartość powinna być wyliczeniem Dock .

Uwaga

Akcesorium get dla dołączonej właściwości jest wymagane do obsługi powiązań danych w narzędziach projektowych, takich jak Visual Studio lub Blend for Visual Studio.

Zestaw metod dostępu

Sygnatura set metody dostępu to public static void Set<property name>(DependencyObject target, object value), gdzie:

  • target to właściwość, DependencyObject na której jest zapisywana dołączona właściwość. Typ target może być bardziej szczegółowy niż DependencyObject. Na przykład SetDock metoda typowa target jako UIElement , ponieważ dołączona właściwość ma być ustawiana na UIElement wystąpieniach. UiElement pośrednio pochodzi z klasy DependencyObject.
  • Typ value może być bardziej szczegółowy niż object. Na przykład SetDock metoda wymaga Dock wartości. Moduł ładujący XAML musi mieć możliwość wygenerowania value typu z ciągu znaczników reprezentującego dołączoną wartość właściwości. W związku z tym musi istnieć konwersja typów, serializator wartości lub obsługa rozszerzenia znaczników dla używanego typu.

Dołączone atrybuty właściwości

WPF definiuje kilka atrybutów platformy .NET, które udostępniają informacje o dołączonych właściwościach do procesów odbicia, a także dla konsumentów informacji o odbiciem i właściwościach, takich jak projektanci. Projektant używać atrybutów platformy .NET zdefiniowanych przez platformę WPF, aby ograniczyć właściwości wyświetlane w oknie właściwości, aby uniknąć przeciążenia użytkowników z globalną listą wszystkich dołączonych właściwości. Możesz rozważyć zastosowanie tych atrybutów do własnych niestandardowych dołączonych właściwości. Przeznaczenie i składnia atrybutów platformy .NET są opisane na tych stronach referencyjnych:

Dowiedz się więcej

  • Aby uzyskać więcej informacji na temat tworzenia dołączonej właściwości, zobacz Rejestrowanie dołączonej właściwości.
  • Aby uzyskać bardziej zaawansowane scenariusze użycia właściwości zależności i dołączone właściwości, zobacz Niestandardowe właściwości zależności.
  • Właściwość można zarejestrować zarówno jako dołączoną właściwość, jak i właściwość zależności, i dołączyć konwencjonalne otoki właściwości. W ten sposób właściwość można ustawić na elemecie przy użyciu otoki właściwości, a także dla dowolnego innego elementu przy użyciu składni właściwości dołączonych XAML. Przykład można znaleźć w temacie FrameworkElement.FlowDirection.

Zobacz też