Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
A csatolt tulajdonság egy XAML-fogalom. A csatolt tulajdonságok általában a függőségi tulajdonság speciális formájaként vannak definiálva. Ez a témakör azt ismerteti, hogyan implementálhat egy csatolt tulajdonságot függőségi tulajdonságként, és hogyan határozhatja meg azt a kiegészítő konvenciót, amely ahhoz szükséges, hogy a csatolt tulajdonság használható legyen az XAML-ben.
Előfeltételek
Feltételezzük, hogy a függőségi tulajdonságokat a meglévő függőségi tulajdonságok fogyasztójának szemszögéből ismeri, és elolvasta a Függőség tulajdonságainak áttekintését. A Csatolt tulajdonságok áttekintését is el kell olvasnia. A jelen témakör példáinak követéséhez ismernie kell az XAML-t is, és tudnia kell, hogyan írhat egy alapszintű Windows-futtatókörnyezeti alkalmazást C++, C# vagy Visual Basic használatával.
A csatolt tulajdonságok forgatókönyvei
Csatolt tulajdonságot akkor hozhat létre, ha oka van annak, hogy a tulajdonságbeállítási mechanizmus a definiáló osztálytól eltérő osztályok számára is elérhető legyen. Ennek leggyakoribb forgatókönyvei az elrendezés és a szolgáltatások támogatása. A meglévő elrendezéstulajdonságok közé tartoznak például a Canvas.ZIndex és a Canvas.Top. Elrendezési forgatókönyvekben az elrendezés-vezérlési elemek gyermekelemeiként létező elemek külön-külön kifejezhetik az elrendezési követelményeket a szülőelemeiknek, és mindegyik beállíthat egy tulajdonságértéket, amelyet a szülő csatolt tulajdonságként határoz meg. A Windows Runtime API szolgáltatástámogatási forgatókönyvére példa a ScrollViewer csatolt tulajdonságainak halmaza, például a ScrollViewer.IsZoomChainingEnabled.
Figyelmeztetés
A Windows Futtatókörnyezet XAML implementációjának meglévő korlátozása, hogy nem lehet animálni az egyéni csatolt tulajdonságot.
Egyéni csatolt tulajdonság regisztrálása
Ha a csatolt tulajdonságot szigorúan más típusokon való használatra definiálja, annak az osztálynak, amelyben a tulajdonság regisztrálva van, nem kell a DependencyObjectből származnia. Ha azonban a szokásos modellt követi, amelyben a csatolt tulajdonság egyben függőségi tulajdonság is, akkor rendelkeznie kell a célparaméterrel az accessorok használatához, hogy használhassa a háttértárolót.
Függőségi tulajdonságként definiálhatja a csatolt tulajdonságot egy nyilvánosstatikusírásvédettDependencyProperty típusú tulajdonság deklarálásával. Ezt a tulajdonságot a RegisterAttached metódus visszatérési értékével definiálhatja. A tulajdonságnévnek meg kell egyeznie a RegisterAttachednévparaméterként megadott csatolt tulajdonságnévvel, és hozzá kell adni a "Property" sztringet a végéhez. Ez a függőségi tulajdonságok azonosítóinak az általuk képviselt tulajdonságokhoz viszonyított elnevezésére szolgáló konvenció.
A fő terület, ahol egy egyéni csatolt tulajdonság definiálása eltér az egyéni függőségi tulajdonságtól, az a kiegészítők vagy burkolók definiálása. Az egyéni függőségi tulajdonságokban leírt burkolótechnika helyett statikus GetPropertyName és Set PropertyName metódusokat is meg kell adnia a csatolt tulajdonság tartozékaként. A tartozékokat többnyire az XAML-elemző használja, bár bármely más hívó is használhatja őket értékek beállítására nem XAML-forgatókönyvekben.
Fontos
Ha nem megfelelően definiálja a tartozékokat, az XAML-processzor nem tud hozzáférni a csatolt tulajdonsághoz, és aki megpróbálja használni, valószínűleg XAML-elemző hibát fog kapni. A tervezési és kódolási eszközök gyakran az "*Property" elnevezési konvenciókra támaszkodnak, amikor egy egyéni függőségi tulajdonságot találnak egy hivatkozott összeállításban.
Accessors
A GetPropertyName hozzáférő aláírásának ilyennek kell lennie.
public static
valueTypeGetPropertyName(DependencyObject target)
A Microsoft Visual Basic esetében ez az.
Public Shared Function Get
Tulajdonságnév(ByVal target As DependencyObject) As valueType)
A célobjektum lehet egy konkrétabb típusú a megvalósításban, de a DependencyObjectből kell származnia. A ValueType visszatérési értéke is lehet egy konkrétabb típus a megvalósításban. Az alapszintű objektumtípus elfogadható, de gyakran azt szeretné, hogy a csatolt tulajdonság megkövetelje a típusbiztonságot. A gépelés használata a getterben és a setter-aláírásokban ajánlott típusbiztonsági technika.
A SetPropertyName tartozék aláírásának ennek kell lennie.
public static void Set
Tulajdonságnév(DependencyObject target ,valueType value)
A Visual Basic esetében ez az.
Public Shared Sub Set
Tulajdonságnév(ByVal target As DependencyObject, ByVal value AsvalueType)
A célobjektum lehet egy konkrétabb típusú a megvalósításban, de a DependencyObjectből kell származnia. Az értékobjektum és a értéktípus az implementációban ennél konkrétabb típusok lehetnek. Ne feledje, hogy ennek a metódusnak az értéke az a bemenet, amelyet a XAML-processzor biztosít, amikor a jelölésben találkozik az Ön csatolt tulajdonságával. A használt típus típuskonvertálásának vagy meglévő korrektúrakiterjesztési támogatásának kell lennie, hogy a megfelelő típust attribútumértékből lehessen létrehozni (ami végső soron csak egy sztring). Az alapszintű objektumtípus elfogadható, de gyakran további típusbiztonságra van szüksége. Ehhez írja be a típusérvényesítést a hozzáférőkbe.
Megjegyzés:
Olyan csatolt tulajdonságot is megadhat, amelyben a kívánt használat a tulajdonságelem szintaxisán keresztül történik. Ebben az esetben nincs szükség típuskonvertálásra az értékekhez, de biztosítania kell, hogy a kívánt értékek XAML-ben is létrehozhatók legyenek. A VisualStateManager.VisualStateGroups egy olyan meglévő csatolt tulajdonság példája, amely csak a tulajdonságelemek használatát támogatja.
Kódrészlet
Ez a példa a függőségi tulajdonság regisztrációját (a RegisterAttached metódus használatával), valamint az egyéni csatolt tulajdonság beolvasását és beállítását mutatja be. A példában a csatolt tulajdonság neve .IsMovable Ezért a hozzáférőket el kell nevezni GetIsMovable és SetIsMovable. A csatolt tulajdonság tulajdonosa egy olyan szolgáltatásosztály, amelynek a neve GameService nem rendelkezik saját felhasználói felülettel; célja csak a csatolt tulajdonságszolgáltatások biztosítása a GameService.IsMovable csatolt tulajdonság használatakor.
A csatolt tulajdonság definiálása a C++/CX-ben egy kicsit összetettebb. El kell döntenie, hogyan kell a fejléc és a kódfájl közötti tényezőt figyelembevenni. Emellett az azonosítót csak egyéni függőségi tulajdonságokban tárgyalt okok miatt egy get hozzáférővel rendelkező tulajdonságként kell elérhetővé tenni. A C++/CX-ben explicit módon kell definiálnia ezt a tulajdonságmező-kapcsolatot ahelyett, hogy egyszerű tulajdonságok NET readonly kulcsszó használatára és implicit háttérrendszerre támaszkodna. A csatolt tulajdonság regisztrációját is végre kell hajtania egy segédfüggvényen belül, amely csak egyszer fut, amikor az alkalmazás először elindul, de a csatolt tulajdonságot igénylő XAML-lapok betöltése előtt. A függőségi vagy kapcsolt tulajdonságok tulajdonságregisztrációs segédfüggvényeinek meghívására általában az app.xaml fájl kódjában található App / osztályának konstruktorában kerül sor.
public class GameService : DependencyObject
{
public static readonly DependencyProperty IsMovableProperty =
DependencyProperty.RegisterAttached(
"IsMovable",
typeof(Boolean),
typeof(GameService),
new PropertyMetadata(false)
);
public static void SetIsMovable(UIElement element, Boolean value)
{
element.SetValue(IsMovableProperty, value);
}
public static Boolean GetIsMovable(UIElement element)
{
return (Boolean)element.GetValue(IsMovableProperty);
}
}
Public Class GameService
Inherits DependencyObject
Public Shared ReadOnly IsMovableProperty As DependencyProperty =
DependencyProperty.RegisterAttached("IsMovable",
GetType(Boolean),
GetType(GameService),
New PropertyMetadata(False))
Public Shared Sub SetIsMovable(ByRef element As UIElement, value As Boolean)
element.SetValue(IsMovableProperty, value)
End Sub
Public Shared Function GetIsMovable(ByRef element As UIElement) As Boolean
GetIsMovable = CBool(element.GetValue(IsMovableProperty))
End Function
End Class
// GameService.idl
namespace UserAndCustomControls
{
[default_interface]
runtimeclass GameService : Windows.UI.Xaml.DependencyObject
{
GameService();
static Windows.UI.Xaml.DependencyProperty IsMovableProperty{ get; };
static Boolean GetIsMovable(Windows.UI.Xaml.DependencyObject target);
static void SetIsMovable(Windows.UI.Xaml.DependencyObject target, Boolean value);
}
}
// GameService.h
...
static Windows::UI::Xaml::DependencyProperty IsMovableProperty() { return m_IsMovableProperty; }
static bool GetIsMovable(Windows::UI::Xaml::DependencyObject const& target) { return winrt::unbox_value<bool>(target.GetValue(m_IsMovableProperty)); }
static void SetIsMovable(Windows::UI::Xaml::DependencyObject const& target, bool value) { target.SetValue(m_IsMovableProperty, winrt::box_value(value)); }
private:
static Windows::UI::Xaml::DependencyProperty m_IsMovableProperty;
...
// GameService.cpp
...
Windows::UI::Xaml::DependencyProperty GameService::m_IsMovableProperty =
Windows::UI::Xaml::DependencyProperty::RegisterAttached(
L"IsMovable",
winrt::xaml_typename<bool>(),
winrt::xaml_typename<UserAndCustomControls::GameService>(),
Windows::UI::Xaml::PropertyMetadata{ winrt::box_value(false) }
);
...
// GameService.h
#pragma once
#include "pch.h"
//namespace WUX = Windows::UI::Xaml;
namespace UserAndCustomControls {
public ref class GameService sealed : public WUX::DependencyObject {
private:
static WUX::DependencyProperty^ _IsMovableProperty;
public:
GameService::GameService();
void GameService::RegisterDependencyProperties();
static property WUX::DependencyProperty^ IsMovableProperty
{
WUX::DependencyProperty^ get() {
return _IsMovableProperty;
}
};
static bool GameService::GetIsMovable(WUX::UIElement^ element) {
return (bool)element->GetValue(_IsMovableProperty);
};
static void GameService::SetIsMovable(WUX::UIElement^ element, bool value) {
element->SetValue(_IsMovableProperty,value);
}
};
}
// GameService.cpp
#include "pch.h"
#include "GameService.h"
using namespace UserAndCustomControls;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Documents;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
GameService::GameService() {};
GameService::RegisterDependencyProperties() {
DependencyProperty^ GameService::_IsMovableProperty = DependencyProperty::RegisterAttached(
"IsMovable", Platform::Boolean::typeid, GameService::typeid, ref new PropertyMetadata(false));
}
Egyéni csatolt tulajdonság beállítása XAML jelölésből
Miután definiálta a csatolt tulajdonságot, és egy egyéni típus részeként belefoglalta annak támogatási tagjait, elérhetővé kell tennie a definíciókat az XAML-használathoz. Ehhez le kell képeznie egy XAML-névteret, amely a megfelelő osztályt tartalmazó kódnévtérre hivatkozik. Azokban az esetekben, amikor a csatolt tulajdonságot egy könyvtár részeként definiálta, a könyvtárat az alkalmazáscsomag részeként kell tartalmaznia.
Az XAML-hez tartozó XML-névtérleképezés általában egy XAML-lap gyökérelemébe kerül. Például a névtérben GameService elnevezett UserAndCustomControls osztály esetében, amely az előző kódrészletekben látható csatolt tulajdonságdefiníciókat tartalmazza, a leképezés így nézhet ki.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:uc="using:UserAndCustomControls"
... >
A leképezés használatával a csatolt tulajdonságot GameService.IsMovable bármely olyan elemre beállíthatja, amely megfelel a céldefiníciónak, beleértve a Windows Runtime által definiált meglévő típust is.
<Image uc:GameService.IsMovable="True" .../>
Ha a tulajdonságot egy olyan elemre állítja be, amely szintén ugyanabban a megfeleltetett XML-névtérben található, akkor is tartalmaznia kell az előtagot a csatolt tulajdonságnéven. Ennek az az oka, hogy az előtag megfelel a tulajdonos típusának. A csatolt tulajdonság attribútuma nem feltételezhető, hogy ugyanabban az XML-névtérben van, mint az az elem, amelyben az attribútum szerepel, annak ellenére, hogy a normál XML-szabályok szerint az attribútumok örökölhetik a névteret az elemektől. Ha például egyéni típust állít be GameService.IsMovable-ra ImageWithLabelControl-ben (a definíció nem jelenik meg), és még akkor is, ha mindkettő ugyanabban a kódnévtérben van meghatározva, amely ugyanahhoz az előtaghoz van rendelve, az XAML struktúrája továbbra is ez lesz.
<uc:ImageWithLabelControl uc:GameService.IsMovable="True" .../>
Megjegyzés:
Ha XAML felhasználói felületet ír C++/CX használatával, akkor a csatolt tulajdonságot meghatározó egyéni típus fejlécét minden alkalommal tartalmaznia kell, amikor egy XAML-lap ezt a típust használja. Minden XAML-oldalhoz tartozik egy kód mögötti fejléc (.xaml.h). Itt kell a csatolt tulajdonság tulajdonostípusának definíciójának fejlécét ( #include használatával) tartalmaznia.
Az egyéni csatolt tulajdonság kényszerítő beállítása
Az imperatív kódból is hozzáférhet egy egyéni csatolt tulajdonsághoz. Az alábbi kód bemutatja, hogyan.
<Image x:Name="gameServiceImage"/>
// MainPage.h
...
#include "GameService.h"
...
// MainPage.cpp
...
MainPage::MainPage()
{
InitializeComponent();
GameService::SetIsMovable(gameServiceImage(), true);
}
...
Egyéni csatolt tulajdonság értéktípusa
Az egyéni csatolt tulajdonság értéktípusaként használt típus befolyásolja a használatot, a definíciót vagy a használatot és a definíciót is. A csatolt tulajdonság értéktípusa több helyen deklarálva van: a Get és a Set kiegészítő metódus aláírásaiban, valamint a RegisterAttached hívás propertyType paramétereként is.
A csatolt tulajdonságok (egyéni vagy egyéb) leggyakoribb értéktípusa egy egyszerű sztring. Ennek az az oka, hogy a csatolt tulajdonságok általában az XAML-attribútumok használatára szolgálnak, és az értéktípusként használt karakterláncok könnyűvé teszik a tulajdonságokat. Más, sztringmetódusokra natívan konvertált primitívek, például egész szám, dupla vagy enumerálási érték is gyakoriak a csatolt tulajdonságok értéktípusaként. A csatolt tulajdonságértékként más értéktípusokat is használhat – azokat, amelyek nem támogatják a natív sztringek konvertálását. Ez azonban azt jelenti, hogy választhat a használatról vagy a megvalósításról:
- A csatolt tulajdonságot elhagyhatja, de a csatolt tulajdonság csak akkor támogatja a használatot, ha a csatolt tulajdonság tulajdonságelem, és az érték objektumelemként van deklarálva. Ebben az esetben a tulajdonságtípusnak támogatnia kell az XAML használatát objektumelemként. Meglévő Windows-futtatókörnyezeti referenciaosztályok esetén ellenőrizze az XAML szintaxist, hogy a típus támogatja-e az XAML objektumelemek használatát.
- A csatolt tulajdonságot változatlanul hagyhatja, de csak attribútumhasználatban használhatja egy XAML referenciatechnikával, például kötéssel vagy StaticResource-nal , amely sztringként fejezhető ki.
További információ a Canvas.Left-példáról
A csatolt tulajdonsághasználatok korábbi példáiban különböző módokon állítottuk be a Canvas.Left csatolt tulajdonságot. De miben változik ez abban, hogy a vászon hogyan kommunikál az objektummal, és mikor történik ez? Ezt a konkrét példát részletesebben is megvizsgáljuk, mert ha egy csatolt tulajdonságot implementál, érdekes látni, hogy egy tipikus csatolt tulajdonságtulajdonosi osztály mit kíván még tenni a csatolt tulajdonságértékeivel, ha más objektumokon találja őket.
A vászon fő funkciója az, hogy abszolút elhelyezésű elrendezéstároló legyen a felhasználói felületen. A vászon gyermekeit egy alaposztályban definiált Gyermek tulajdonság tárolja. Az összes panel közül a Vászon az egyetlen, amely abszolút pozicionálást használ. Az általános UIElement-típus objektummodelljét elárasztotta volna, ha olyan tulajdonságokat adnánk hozzá, amelyek csak a Canvas-hoz és azokhoz a konkrét UIElement esetekhez kapcsolódnak, amikor ezek egy UIElement gyermekelemei. A Canvas elrendezésvezérlő tulajdonságainak meghatározása csatolt tulajdonságokként, amelyeket bármely UIElement használhat, tisztábban tartja az objektummodellt.
Gyakorlati panelként a Canvas olyan viselkedéssel rendelkezik, amely felülbírálja a keretrendszerszintű mérték - és rendezési módszereket. Itt ellenőrzi a Canvas a gyermekekhez csatolt tulajdonságértékeket. Mind a Mérték , mind az Elrendezés minták része egy hurok, amely minden tartalom felett iterál, és a panelen a Children tulajdonság látható, amely explicitvé teszi, hogy mit kellene egy panel gyermekének tekinteni. A Vászon elrendezés viselkedése tehát végigfut ezeken a gyermekeken, és statikus Canvas.GetLeft és Canvas.GetTop hívásokat indít minden gyermeken, hogy lássa, a csatolt tulajdonságok tartalmaznak-e nem alapértelmezett értéket (alapértelmezés szerint 0). Ezeket az értékeket ezután a rendszer a gyermek által megadott értékeknek megfelelően a vászon rendelkezésre álló elrendezési területén lévő összes gyermek abszolút elhelyezésére használja, és az Elrendezés funkcióval véglegesít.
A kód ehhez a pszeudokódhoz hasonló.
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement child in Children)
{
double x = (double) Canvas.GetLeft(child);
double y = (double) Canvas.GetTop(child);
child.Arrange(new Rect(new Point(x, y), child.DesiredSize));
}
return base.ArrangeOverride(finalSize);
// real Canvas has more sophisticated sizing
}
Megjegyzés:
A panelek működéséről további információt az XAML egyéni panelek áttekintésében talál.
Kapcsolódó témakörök
Windows developer