Omówienie dołączonych właściwości
Dołączona właściwość jest koncepcją zdefiniowaną przez język XAML. Dołączona właściwość ma być używana jako typ właściwości globalnej, która jest ustawiana na dowolnym obiekcie zależności. W programie Windows Presentation Foundation (WPF) dołączone właściwości są zwykle definiowane jako wyspecjalizowana forma właściwości zależności, która nie ma konwencjonalnej właściwości "otoka".
Wymagania wstępne
W tym artykule założono, że rozumiesz właściwości zależności z perspektywy konsumenta istniejących właściwości zależności w klasach Windows Presentation Foundation (WPF) oraz przeczytałeś Właściwości zależności — omówienie. Aby postępować zgodnie z przykładami w tym artykule, należy również zrozumieć język XAML i wiedzieć, jak pisać aplikacje WPF.
Dlaczego warto używać dołączonych właściwości
Jednym z celów dołączonej właściwości jest umożliwienie różnym elementom podrzędnym określania unikatowych wartości właściwości zdefiniowanej w elemencie nadrzędnym. Konkretną aplikacją tego scenariusza jest posiadanie elementów podrzędnych, które informują element nadrzędny o tym, jak mają być prezentowane w interfejsie użytkownika. Przykładem jest właściwość DockPanel.Dock. Właściwość DockPanel.Dock jest tworzona jako dołączona właściwość, ponieważ została zaprojektowana do ustawiania elementów zawartych w DockPanel, a nie na samym DockPanel. Klasa DockPanel definiuje pole statyczne DependencyProperty o nazwie DockProperty, a następnie udostępnia metody GetDock i SetDock jako publiczne metody dostępu dla dołączonej właściwości.
Dołączone właściwości w XAML
W języku XAML ustawiasz dołączone właściwości przy użyciu składni AttachedPropertyProvider.PropertyName
Poniżej przedstawiono przykład sposobu ustawiania DockPanel.Dock w języku XAML:
<DockPanel>
<TextBox DockPanel.Dock="Top">Enter text</TextBox>
</DockPanel>
Użycie jest nieco podobne do właściwości statycznej; Zawsze odwołujesz się do typu DockPanel, który jest właścicielem i rejestruje dołączoną właściwość, zamiast odwoływać się do dowolnego wystąpienia określonego przez nazwę.
Ponadto, ponieważ dołączona właściwość w języku XAML jest atrybutem ustawianym w znacznikach, tylko operacja ustawiania ma jakiekolwiek znaczenie. Nie można bezpośrednio uzyskać właściwości w języku XAML, chociaż istnieją pewne mechanizmy pośrednie do porównywania wartości, takich jak wyzwalacze w stylach (aby uzyskać szczegółowe informacje, zobacz Styling and Templating).
Implementacja dołączonej właściwości w WPF
W programie Windows Presentation Foundation (WPF) większość dołączonych właściwości interfejsu użytkownika w typach WPF jest implementowana jako właściwości zależności. Dołączone właściwości są koncepcją XAML, natomiast właściwości zależności są koncepcją WPF. Ponieważ właściwości dołączone w WPF są właściwościami zależności, obsługują pojęcia właściwości zależności, takie jak metadane właściwości i wartości domyślne z tych metadanych właściwości.
Jak dołączone właściwości są używane przez typ będący właścicielem
Mimo że dołączone właściwości są ustawiane na dowolnym obiekcie, nie oznacza to automatycznie, że ustawienie właściwości spowoduje wygenerowanie namacalnego wyniku lub że wartość będzie kiedykolwiek używana przez inny obiekt. Ogólnie rzecz biorąc, dołączone właściwości są przeznaczone tak, aby obiekty pochodzące z szerokiej gamy możliwych hierarchii klas lub relacji logicznych mogły zgłaszać typowe informacje do typu definiującego dołączoną właściwość. Typ definiujący dołączoną właściwość zwykle jest zgodny z jednym z następujących modeli:
Typ definiujący dołączoną właściwość jest zaprojektowany tak, aby mógł być elementem nadrzędnym elementów, które będą ustawiać wartości dla dołączonej właściwości. Następnie typ iteruje swoje obiekty podrzędne za pomocą logiki wewnętrznej względem struktury 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ść będzie wykorzystywany w roli elementu podrzędnego dla różnych możliwych elementów nadrzędnych i modeli zawartości.
Typ definiujący dołączoną właściwość reprezentuje usługę. Inne typy ustawiają wartości dla powiązanej właściwości. Następnie, gdy element, który ustawił właściwość, jest analizowany w kontekście usługi, wartości dołączonych właściwości są uzyskiwane za pomocą wewnętrznej logiki klasy usługi.
Przykład właściwości dołączonej z identyfikatorem Parent-Defined
Najbardziej typowym scenariuszem, w którym WPF definiuje dołączoną właściwość, jest to, że element nadrzędny obsługuje kolekcję elementów podrzędnych, a także implementuje zachowanie, w którym szczegóły zachowania są zgłaszane indywidualnie dla każdego elementu podrzędnego.
DockPanel definiuje dołączoną właściwość DockPanel.Dock, a DockPanel ma kod na poziomie klasy w ramach logiki renderowania (w szczególności MeasureOverride i ArrangeOverride). Wystąpienie DockPanel zawsze sprawdza, czy którykolwiek z jego bezpośrednich elementów podrzędnych ma ustawioną wartość dla DockPanel.Dock. Jeśli tak, te wartości stają się danymi wejściowymi logiki renderowania zastosowanej do tego konkretnego elementu podrzędnego. Zagnieżdżone wystąpienia DockPanel każde traktuje swoje własne kolekcje elementów podrzędnych, ale to zachowanie jest specyficzne dla tego, jak DockPanel przetwarza wartości DockPanel.Dock. Teoretycznie możliwe jest, aby załączone właściwości wpływały na elementy wykraczające poza bezpośredniego rodzica. Jeśli właściwość dołączona DockPanel.Dock jest ustawiona na elemencie, który nie ma elementu nadrzędnego DockPanel do działania na nim, nie zostanie zgłoszony żaden błąd ani wyjątek. Oznacza to po prostu, że wartość właściwości globalnej została ustawiona, ale nie ma bieżącego elementu nadrzędnego DockPanel, który mógłby korzystać z tych informacji.
Dołączone właściwości w kodzie
Dołączone właściwości w WPF nie mają typowych metod opakowań CLR umożliwiających łatwy odczyt i zapis. Jest to spowodowane tym, że dołączona właściwość nie musi być częścią przestrzeni nazw CLR dla wystąpień, w których właściwość jest ustawiona. Jednak procesor XAML musi być w stanie ustawić te wartości, gdy kod XAML jest analizowany. Aby zapewnić obsługę efektywnego użycia dołączonych właściwości, typ właściciela dołączonej właściwości musi zaimplementować dedykowane metody dostępu w postaci GetPropertyName i SetPropertyName. Te dedykowane metody dostępu są również przydatne do uzyskiwania lub ustawiania dołączonej właściwości w kodzie. Z perspektywy kodu dołączona właściwość jest podobna do pola zapasowego, które ma metody dostępu zamiast metod dostępu do właściwości, a pole zapasowe może istnieć na dowolnym obiekcie, a nie musi być specjalnie zdefiniowane.
W poniższym przykładzie pokazano, jak ustawić dołączoną właściwość w kodzie. W tym przykładzie myCheckBox
jest wystąpieniem klasy CheckBox.
DockPanel myDockPanel = new DockPanel();
CheckBox myCheckBox = new CheckBox();
myCheckBox.Content = "Hello";
myDockPanel.Children.Add(myCheckBox);
DockPanel.SetDock(myCheckBox, Dock.Top);
Dim myDockPanel As New DockPanel()
Dim myCheckBox As New CheckBox()
myCheckBox.Content = "Hello"
myDockPanel.Children.Add(myCheckBox)
DockPanel.SetDock(myCheckBox, Dock.Top)
Podobnie jak w przypadku XAML, jeśli myCheckBox
nie został jeszcze dodany jako element podrzędny myDockPanel
przez czwarty wiersz kodu, piąty wiersz kodu nie zgłosi wyjątku, ale wartość właściwości nie wchodziłaby w interakcję z elementem nadrzędnym DockPanel i w ten sposób nic nie zrobiłaby. Tylko wartość DockPanel.Dock ustawiona na element podrzędny w połączeniu z obecnością elementu nadrzędnego DockPanel spowoduje skuteczne zachowanie w renderowanej aplikacji. (W tym przypadku można ustawić dołączoną właściwość, a następnie dołączyć do drzewa. Możesz też dołączyć do drzewa, a następnie ustawić dołączoną właściwość. Każda kolejność akcji zawiera ten sam wynik.
Metadane dołączonej właściwości
Podczas rejestrowania właściwości FrameworkPropertyMetadata jest ustawiona, aby określić charakterystyki właściwości, takie jak to, czy właściwość ma wpływ na renderowanie, pomiar i tak dalej. Metadane dołączonej właściwości zwykle nie różnią się od właściwości zależności. Jeśli określisz wartość domyślną w zastąpieniu metadanych dołączonej właściwości, ta wartość stanie się wartością domyślną domyślnej dołączonej właściwości w wystąpieniach klasy, która dokonuje zastąpienia. W szczególności Twoja domyślna wartość jest zgłaszana, jeśli jakieś zapytania wykonywane przez proces dotyczą wartości dołączonej właściwości za pośrednictwem metody dostępowej Get
dla tej właściwości, określając wystąpienie klasy, w którym zdefiniowano metadane, i wartość dla tej dołączonej właściwości nie została ustawiona w inny sposób.
Jeśli chcesz włączyć dziedziczenie wartości we właściwości, należy użyć właściwości dołączanych, a nie właściwości zależności bez dołączania. Aby uzyskać szczegółowe informacje, zobacz dziedziczenie wartości atrybutów.
Niestandardowe dołączone właściwości
Kiedy utworzyć dołączoną właściwość
Możesz utworzyć dołączoną właściwość, gdy istnieje powód, aby mechanizm ustawiania właściwości był dostępny dla klas innych niż klasa definiująca. Najbardziej typowym scenariuszem jest układ. Przykłady istniejących właściwości układu to DockPanel.Dock, Panel.ZIndexi Canvas.Top. W tym scenariuszu włączono, że elementy, które istnieją jako elementy podrzędne do elementów sterujących układem, są w stanie wyrazić wymagania układu do ich elementów nadrzędnych układu indywidualnie, z których każdy ustawia wartość właściwości zdefiniowanej przez element nadrzędny jako dołączoną właściwość.
Innym scenariuszem użycia dołączonej właściwości jest sytuacja, gdy twoja klasa reprezentuje usługę i chcesz, aby inne klasy mogły ją integrować bardziej przejrzyście.
Kolejnym scenariuszem jest otrzymanie wsparcia projektanta WPF w Visual Studio, na przykład edytowania okna właściwości . Aby uzyskać więcej informacji, zobacz Przegląd tworzenia interfejsów sterowania.
Jak wspomniano wcześniej, należy zarejestrować właściwość jako dołączoną, jeśli 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ść ściśle do użycia w innych typach, klasa nie musi pochodzić z DependencyObject. Ale musisz dziedziczyć z DependencyObject, jeśli przestrzegasz ogólnego modelu WPF, aby posiadana właściwość dołączona była także właściwością zależności.
Zdefiniuj dołączoną właściwość jako właściwość zależności, deklarując pole public static readonly
typu DependencyProperty. To pole definiuje się przy użyciu wartości zwracanej metody RegisterAttached. Nazwa pola musi być zgodna z dołączoną nazwą właściwości, rozszerzoną o ciąg Property
, aby odpowiadała ustalonemu wzorcowi WPF nazewnictwa pól identyfikujących w porównaniu z właściwościami, które reprezentują. Dostawca dołączonej właściwości musi również udostępnić statyczne metody GetPropertyName oraz SetPropertyName jako akcesory dla dołączonej właściwości; niezrobienie tego spowoduje, że system właściwości nie będzie mógł użyć Twojej dołączonej właściwości.
Notatka
Jeśli pominięto metodę dostępu dołączonej właściwości, powiązanie danych we właściwości nie będzie działać w narzędziach projektowych, takich jak Visual Studio i Blend for Visual Studio.
Akcesor Get
Podpis metody dostępu GetPropertyName musi być:
public static object GetPropertyName(object target)
Obiekt
target
można określić jako bardziej szczegółowy typ w Twojej implementacji. Na przykład metoda DockPanel.GetDock wpisze parametr jako UIElement, ponieważ dołączona właściwość ma być ustawiona tylko na wystąpieniach UIElement.Wartość zwracaną można określić jako bardziej konkretny typ w implementacji. Na przykład metoda GetDock wpisze ją jako Dock, ponieważ wartość można ustawić tylko na tę wyliczenie.
Zestaw akcesoriów
Sygnatura akcesora ustawiającego właściwośćPropertyName musi być następująca:
public static void SetPropertyName(object target, object value)
Obiekt
target
można określić jako bardziej szczegółowy typ w Twojej implementacji. Na przykład metoda SetDock wpisze ją jako UIElement, ponieważ dołączona właściwość ma być ustawiona tylko na wystąpieniach UIElement.Obiekt
value
można określić jako bardziej szczegółowy typ w twojej implementacji. Na przykład metoda SetDock klasyfikuje ją jako Dock, ponieważ wartość można ustawić tylko na to wyliczenie. Pamiętaj, że wartość dla tej metody to dane wejściowe pochodzące z modułu ładującego XAML, gdy napotyka on dołączoną właściwość w kontekście użycia dołączonej właściwości w znacznikach. Te dane wejściowe są wartością określoną jako wartość atrybutu XAML w adiustacji. W związku z tym musi istnieć konwersja typu, serializator wartości lub obsługa rozszerzenia znaczników dla używanego typu, tak aby można było utworzyć odpowiedni typ na podstawie wartości atrybutu (która ostatecznie jest tylko ciągiem).
W poniższym przykładzie przedstawiono rejestrację właściwości zależności (przy użyciu metody RegisterAttached), a także GetPropertyName i SetPropertyName metod dostępu. W tym przykładzie dołączona nazwa właściwości to IsBubbleSource
. W związku z tym metody dostępu muszą mieć nazwę GetIsBubbleSource
i SetIsBubbleSource
.
public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
"IsBubbleSource",
typeof(Boolean),
typeof(AquariumObject),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
);
public static void SetIsBubbleSource(UIElement element, Boolean value)
{
element.SetValue(IsBubbleSourceProperty, value);
}
public static Boolean GetIsBubbleSource(UIElement element)
{
return (Boolean)element.GetValue(IsBubbleSourceProperty);
}
Public Shared ReadOnly IsBubbleSourceProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsBubbleSource", GetType(Boolean), GetType(AquariumObject), New FrameworkPropertyMetadata(False, FrameworkPropertyMetadataOptions.AffectsRender))
Public Shared Sub SetIsBubbleSource(ByVal element As UIElement, ByVal value As Boolean)
element.SetValue(IsBubbleSourceProperty, value)
End Sub
Public Shared Function GetIsBubbleSource(ByVal element As UIElement) As Boolean
Return CType(element.GetValue(IsBubbleSourceProperty), Boolean)
End Function
Atrybuty przypisanej właściwości
WPF definiuje kilka atrybutów platformy .NET, które mają dostarczać informacji o właściwościach dołączonych do procesów refleksji oraz typowych użytkownikach informacji na temat refleksji i właściwości, takich jak projektanci. Ponieważ dołączone właściwości mają typ nieograniczonego zakresu, projektanci potrzebują sposobu, aby uniknąć przeciążenia użytkowników z globalną listą wszystkich dołączonych właściwości zdefiniowanych w określonej implementacji technologii korzystającej z języka XAML. Atrybuty platformy .NET zdefiniowane przez WPF dla dołączonych właściwości mogą służyć do określania zakresu sytuacji, w których dana dołączona właściwość powinna być wyświetlana w oknie właściwości. Możesz również rozważyć zastosowanie tych atrybutów dla własnych niestandardowych przypisanych właściwości. Przeznaczenie i składnia atrybutów platformy .NET są opisane na odpowiednich stronach referencyjnych:
Dowiedz się więcej o dołączonych właściwościach
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łączonych właściwości, zobacz Właściwości zależności niestandardowych.
Możesz również zarejestrować właściwość jako dołączoną właściwość i jako właściwość zależności, ale nadal uwidaczniać implementacje "opakowania". W takim przypadku właściwość można ustawić na tym elemecie lub na dowolnym elemecie za pomocą składni właściwości dołączonej XAML. Przykładem właściwości z odpowiednim scenariuszem dla użycia standardowego i dołączonego jest FrameworkElement.FlowDirection.
Zobacz też
.NET Desktop feedback