Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A Windows Presentation Foundation (WPF) alkalmazásfejlesztői és az összetevő-készítők egyéni függőségi tulajdonságokat hozhatnak létre a tulajdonságaik funkcióinak kibővítéséhez. A közös nyelvi futtatókörnyezettől (CLR) tulajdonságtóleltérően a függőségi tulajdonság támogatja a stílust, az adatkötést, az öröklést, az animációkat és az alapértelmezett értékeket. Background, Widthés Text példák a WPF-osztályok meglévő függőségi tulajdonságaira. Ez a cikk bemutatja az egyéni függőségi tulajdonságok implementálását, valamint a teljesítmény, a használhatóság és a sokoldalúság javítására szolgáló lehetőségeket.
Előfeltételek
A cikk feltételezi a függőségi tulajdonságok alapszintű ismeretét, és hogy elolvasta függőségi tulajdonságok áttekintését. A cikkben szereplő példák követéséhez segít, ha ismeri az Extensible Application Markup Language (XAML) nyelvet, és ismeri a WPF-alkalmazások írásának módját.
Függőségi tulajdonság azonosítója
A függőségi tulajdonságok olyan tulajdonságok, amelyek Register vagy RegisterReadOnly hívásokon keresztül vannak regisztrálva a WPF-tulajdonságrendszerben. A Register metódus egy DependencyProperty példányt ad vissza, amely egy függőségi tulajdonság regisztrált nevét és jellemzőit tartalmazza. A DependencyProperty példányt egy statikus írásvédett mezőhöz rendeli, amelyet függőségi tulajdonságazonosítóként ismerneknéven, amelyet konvenció szerint <property name>Property-nak neveznek. A Background tulajdonság azonosítómezője például mindig BackgroundProperty.
A függőségi tulajdonságazonosító a tulajdonságértékek lekéréséhez vagy beállításához használható háttérmezőként, nem pedig egy privát mezővel rendelkező tulajdonság biztonsági mentésének szabványos mintájaként. A tulajdonságrendszer nem csak az azonosítót használja, az XAML-processzorok is használhatják, és a kód (és esetleg külső kód) az azonosítójukon keresztül hozzáférhet a függőségi tulajdonságokhoz.
A függőségi tulajdonságok csak DependencyObject típusú osztályokra alkalmazhatók. A legtöbb WPF-osztály támogatja a függőségi tulajdonságokat, mert DependencyObject közel van a WPF-osztályhierarchia gyökeréhez. A függőségi tulajdonságokról, valamint a leírásukhoz használt terminológiáról és konvenciókról további információt Függőség tulajdonságainak áttekintésecímű témakörben talál.
Függőségi tulajdonságburkolók
A nem csatolt WPF-függőségi tulajdonságokat egy CLR-burkoló teszi elérhetővé, amely get és set tartozékokat implementál. A tulajdonságburkoló használatával a függőségi tulajdonságok felhasználói ugyanúgy kaphatnak vagy állíthatnak be függőségi tulajdonságértékeket, mint bármely más CLR-tulajdonságot. A get és set tartozékai DependencyObject.GetValue és DependencyObject.SetValue hívásokon keresztül kommunikálnak a mögöttes tulajdonságrendszerrel, paraméterként átadva a függőségi tulajdonság azonosítót. A függőségi tulajdonságok felhasználói általában nem hívják meg közvetlenül a(z) GetValue vagy SetValue metódusokat, de ha egyéni függőségi tulajdonságot valósít meg, akkor ezeket a metódusokat fogja használni a burkolóban.
Mikor kell implementálni egy függőségi tulajdonságot?
Amikor egy DependencyObjectszármaztatott osztályban implementál egy tulajdonságot, függőségi tulajdonságként teheti meg, ha a tulajdonságot egy DependencyProperty azonosítóval alátámasztja. A forgatókönyvtől függ, hogy hasznos-e függőségi tulajdonságot létrehozni. Bár a tulajdonság magánmezővel való alátámasztása bizonyos helyzetekben megfelelő, érdemes lehet egy függőségi tulajdonságot alkalmazni, ha azt szeretné, hogy a tulajdonság támogassa az alábbi WPF-képességek egyikét:
Stíluson belül beállítható tulajdonságok. További információ: Stílusok és sablonok.
Az adatkötést támogató tulajdonságok. További információ az adatkötés függőségi tulajdonságairól: Két vezérlő tulajdonságainak kötése
Dinamikus erőforrás-hivatkozásokon keresztül beállítható tulajdonságok. További információ: XAML-erőforrások.
Azok a tulajdonságok, amelyek automatikusan öröklik az értéküket az elemfa szülőelemétől. Ehhez regisztrálnia kell a RegisterAttachedhasználatával, még akkor is, ha egy tulajdonságburkolót is létrehoz a CLR-hozzáféréshez. További információ: Tulajdonságérték öröklése.
Animálható tulajdonságok. További információ: Animáció – áttekintés
A WPF tulajdonságrendszer értesítése, ha egy tulajdonság értéke megváltozik. A módosítások oka lehet a tulajdonságrendszer, a környezet, a felhasználó vagy a stílusok műveletei. A tulajdonság megadhat egy visszahívási módszert a tulajdonság metaadataiban, amelyet minden alkalommal meghív, amikor a tulajdonságrendszer megállapítja, hogy a tulajdonság értéke megváltozott. A kapcsolódó fogalom a tulajdonságérték-kényszerítés. További információért tekintse meg a függőségi tulajdonság visszahívásait és érvényesítését.
Hozzáférés a függőségi tulajdonság metaadataihoz, amelyeket a WPF-folyamatok olvasnak. A tulajdonság metaadatait például a következő célokra használhatja:
Adja meg, hogy a módosított függőségi tulajdonságértékek miatt az elrendezési rendszer újrakomponáljon-e vizualizációkat egy elemhez.
Állítsa be egy függőségi tulajdonság alapértelmezett értékét a származtatott osztályok metaadatainak felülírásával.
A Visual Studio WPF tervezői támogatása, például egy egyéni vezérlő tulajdonságainak szerkesztése a Tulajdonságok ablakban. További információ: A szerzői műveletek szabályozása – áttekintés
Bizonyos esetekben egy meglévő függőségi tulajdonság metaadatainak felülírása jobb megoldás, mint egy új függőségi tulajdonság implementálása. Az, hogy egy metaadat-felülírás hasznos-e, a konkrét forgatókönyvtől függ, és attól, hogy ez a forgatókönyv milyen mértékben hasonlít a meglévő WPF függőségi tulajdonságok és osztályok implementálására. A meglévő függőségi tulajdonságok metaadatainak felülírásáról további információt Függőség tulajdonság metaadataicímű témakörben talál.
Függőségi tulajdonság létrehozásának ellenőrzőlistája
A függőségi tulajdonság létrehozásához kövesse az alábbi lépéseket. A lépések némelyike egyetlen kódsorban kombinálható és implementálható.
(Nem kötelező) Függőségi tulajdonság metaadatainak létrehozása.
Regisztrálja a függőségi tulajdonságot a tulajdonságrendszerben, megadva egy tulajdonságnevet, egy tulajdonostípust, a tulajdonságérték típusát és opcionálisan a tulajdonság metaadatait.
Adjon meg egy DependencyProperty azonosítót
public static readonlymezőként a tulajdonostípuson. Az azonosító mező neve azPropertyutótaggal rendelkező tulajdonságnév.Definiáljon egy CLR-burkoló tulajdonságot, amelynek neve megegyezik a függőségi tulajdonság nevével. A CLR-burkolóban implementáljon
getéssetelérőket, amelyek a burkoló háttérfüggőségi tulajdonságához kapcsolódnak.
A tulajdonság regisztrálása
Ahhoz, hogy a tulajdonság függőségi tulajdonság legyen, regisztrálnia kell azt a tulajdonságrendszerben. A tulajdonság regisztrálásához hívja meg a Register metódust az osztály törzséből, de a tagdefiníciókon kívül. A Register metódus egy egyedi függőségi tulajdonságazonosítót ad vissza, amelyet a tulajdonságrendszer API-jának meghívásakor fog használni. A Register hívás azért történik tagdefiníciókon kívül, mert a visszatérési értéket egy public static readonly típusú DependencyPropertymezőhöz rendeli. Ez a mező, amelyet az osztályban fog létrehozni, a függőségi tulajdonság azonosítója. Az alábbi példában a Register első argumentuma a függőségi tulajdonság AquariumGraphicnevet adja.
// 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))
);
' 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)))
Megjegyzés:
Az osztálytörzs függőségi tulajdonságának meghatározása a tipikus implementáció, de az osztály statikus konstruktorában is definiálható függőségi tulajdonság. Ennek a megközelítésnek akkor lehet értelme, ha több kódsorra van szüksége a függőségi tulajdonság inicializálásához.
Függőségi tulajdonság elnevezése
A függőségi tulajdonságokra vonatkozó elfogadott elnevezési konvenció kötelező a tulajdonságrendszer normál viselkedéséhez. A létrehozott azonosítómezőnek a tulajdonság regisztrált nevének kell lennie a Propertyutótaggal.
A függőségi tulajdonság nevének egyedinek kell lennie a regisztrációs osztályon belül. Az alaptípuson öröklő függőségi tulajdonságok már regisztrálva vannak, és származtatott típussal nem regisztrálhatók. Használhat azonban egy olyan függőségi tulajdonságot, amely egy másik típussal lett regisztrálva, még egy olyan típust is, amelytől az osztály nem öröklődik, ha hozzáadja az osztályt a függőségi tulajdonság tulajdonosaként. További információ az osztály tulajdonosként való hozzáadásáról: Függőség tulajdonság metaadatai.
Tulajdonságburkoló implementálása
Konvenció szerint a burkoló tulajdonság nevének meg kell egyeznie a Register hívás első paraméterével, amely a függőségi tulajdonság neve. A burkoló implementáció meghívja GetValue a get tartozékban, és SetValue a set tartozékban (olvasási-írási tulajdonságokhoz). Az alábbi példa egy burkolót mutat be, amely követi a regisztrációs hívást és az azonosító mező deklarálását. A WPF-osztályok összes nyilvános függőségi tulajdonsága hasonló burkolómodellt használ.
// 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))
);
// Declare a read-write property wrapper.
public Uri AquariumGraphic
{
get => (Uri)GetValue(AquariumGraphicProperty);
set => SetValue(AquariumGraphicProperty, value);
}
' 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)))
' Declare a read-write property wrapper.
Public Property AquariumGraphic As Uri
Get
Return CType(GetValue(AquariumGraphicProperty), Uri)
End Get
Set
SetValue(AquariumGraphicProperty, Value)
End Set
End Property
Ritka esetek kivételével a burkoló implementációnak csak GetValue és SetValue kódot kell tartalmaznia. Ennek okait Egyéni függőségi tulajdonságokra vonatkozó következményekcímű témakörben talál.
Ha az ingatlan nem követi a már elfogadott elnevezési konvenciókat, a következő problémákkal találkozhat:
A stílusok és sablonok bizonyos aspektusai nem működnek.
A legtöbb eszköz és tervező az elnevezési konvenciókra támaszkodva megfelelően szerializálja az XAML-t, és tervezői környezetben nyújt segítséget tulajdonságonként.
A WPF XAML rakodó jelenlegi implementációja teljes mértékben áthalad a burkolón, és az elnevezési konvencióra támaszkodik az attribútumértékek feldolgozásához. További információ: XAML betöltési és függőségi tulajdonságok.
Függőségi tulajdonság metaadatai
Függőségi tulajdonság regisztrálásakor a tulajdonságrendszer létrehoz egy metaadat-objektumot a tulajdonság jellemzőinek tárolásához. A Register metódus túlterhelése lehetővé teszi a tulajdonság metaadatainak megadását a regisztráció során, például Register(String, Type, Type, PropertyMetadata). A tulajdonság metaadatok egyik gyakori felhasználása egy egyedi alapértelmezett érték beállítása olyan új példányokhoz, amelyek függőségi tulajdonságot használnak. Ha nem ad meg tulajdonság metaadatokat, a tulajdonságrendszer számos függőségi tulajdonságtulajdonsághoz rendel alapértelmezett értékeket.
Ha függőségi tulajdonságot hoz létre egy FrameworkElementszármaztatott osztályon, a speciálisabb metaadatosztály-FrameworkPropertyMetadata használhatja az alaposztály PropertyMetadatahelyett. Számos FrameworkPropertyMetadata konstruktor-aláírás lehetővé teszi a metaadat-jellemzők különböző kombinációinak megadását. Ha csak egy alapértelmezett értéket szeretne megadni, használja a FrameworkPropertyMetadata(Object), és adja át az alapértelmezett értéket a Object paraméternek. Győződjön meg arról, hogy az értéktípus megegyezik a propertyType-val, amely a Register hívásban van megadva.
Néhány FrameworkPropertyMetadata túlterhelés lehetővé teszi metaadat-beállításjelölők megadását a tulajdonsághoz. A tulajdonságrendszer ezeket a jelzőket különálló tulajdonságokká alakítja, és a jelölőértékeket a WPF-folyamatok, például az elrendezési motor használják.
Metaadat-jelzők beállítása
A metaadat-jelzők beállításakor vegye figyelembe a következőket:
Ha a tulajdonság értéke (vagy annak módosítása) befolyásolja, hogy az elrendezési rendszer hogyan jelenít meg egy felhasználói felületi elemet, állítsa be az alábbi jelölők egyikét vagy többét:
AffectsMeasure, amely azt jelzi, hogy a tulajdonságérték módosítása a felhasználói felület renderelésének módosítását igényli, különösen azt a helyet, amelyet egy objektum foglal el a szülőjében. Állítsa be például ezt a metaadat-jelzőt egy
Widthtulajdonsághoz.AffectsArrange, amely azt jelzi, hogy a tulajdonságérték módosítása a felhasználói felület renderelésének megváltoztatását igényli, különösen egy objektum szülőben elfoglalt helyét. Az objektum mérete általában nem változik. Állítsa be például ezt a metaadat-jelzőt egy
Alignmenttulajdonsághoz.AffectsRender, amely azt jelzi, hogy olyan változás történt, amely nem befolyásolja az elrendezést és a mértéket, de továbbra is szükség van egy újabb renderelésre. Állítsa be például ezt a jelölőt egy
Backgroundtulajdonsághoz, vagy bármely más tulajdonsághoz, amely hatással van egy elem színére.
Ezeket a jelzőket a tulajdonságrendszer (vagy elrendezés) visszahívásainak felülbírálási implementációihoz is használhatja bemenetként. Előfordulhat például, hogy OnPropertyChanged visszahívással hívja meg InvalidateArrange, ha a példány egy tulajdonsága értékváltozást jelez, és AffectsArrange metaadatokban van beállítva.
Egyes tulajdonságok más módon befolyásolják a szülőelem renderelési jellemzőit. A MinOrphanLines tulajdonság módosítása például módosíthatja a folyamatdokumentumok teljes renderelését. A AffectsParentArrange vagy AffectsParentMeasure használatával jelezheti a szülőműveleteket a saját tulajdonságaiban.
Alapértelmezés szerint a függőségi tulajdonságok támogatják az adatkötést. A IsDataBindingAllowed azonban letilthatja az adatkötést, ha nincs reális forgatókönyve, vagy ha az adatkötés teljesítménye problémás, például nagy objektumokon.
Bár a függőségi tulajdonságok adatközési módját egy konkrét kötés esetén OneWay-ra módosíthatja. További információ: Kötés iránya. Függőségi tulajdonság szerzőjeként úgy dönthet, hogy a kétirányú kötés legyen az alapértelmezett mód. A kétirányú adatkötést használó meglévő függőségi tulajdonságra példa a MenuItem.IsSubmenuOpen, amelynek állapota más tulajdonságokon és metódushívásokon alapul. A
IsSubmenuOpenforgatókönyve az, hogy a beállítási logika és a MenuItemösszeállítása az alapértelmezett témastílust használja. TextBox.Text egy másik WPF függőségi tulajdonság, amely alapértelmezés szerint kétirányú kötést használ.A függőségi tulajdonság tulajdonságöröklését a Inherits jelző beállításával engedélyezheti. A tulajdonságöröklés olyan helyzetekben hasznos, amelyekben a szülő- és gyermekelemek közös tulajdonságot tartalmaznak, és a gyermekelemnek érdemes örökölnie a közös tulajdonság szülőértékét. Egy örökölhető tulajdonságra példa, DataContextamely támogatja a master-detail forgatókönyvet használó kötési műveleteket
Állítsa be a Journal jelzőt, amely jelzi, hogy a függőségi tulajdonságot a navigációs naplózási szolgáltatásoknak kell észlelnie vagy használnia. Például a SelectedIndex tulajdonság úgy állítja be a
Journaljelzőt, hogy javasolja az alkalmazásoknak az elemek kijelölt naplózási előzményeinek megőrzését.
Írásvédett függőség tulajdonságai
Megadhat egy írásvédett függőségi tulajdonságot. Egy tipikus forgatókönyv az, amikor egy függőségi tulajdonság belső állapotot tárol. A IsMouseOver például írásvédett, mert állapotát csak az egér bemenete határozza meg. További információ: írásvédett függőség tulajdonságai.
Gyűjtemény típusú függőség tulajdonságai
A gyűjtemény típusú függőségi tulajdonságok további megvalósítási problémákat is figyelembe veendők, például a referenciatípusok alapértelmezett értékének beállítása és a gyűjteményelemek adatkötési támogatása. További információ: Gyűjtemény típusú függőség tulajdonságai.
A függőségi tulajdonságok biztonsága
A függőségi tulajdonságokat általában nyilvános tulajdonságokként, DependencyProperty azonosító mezőket pedig public static readonly mezőként kell deklarálni. Ha szigorúbb hozzáférési szintet (például protected) ad meg, a függőségi tulajdonság továbbra is elérhető az azonosítón keresztül a tulajdonságrendszer API-ival kombinálva. Még egy védett azonosító mező is elérhető a WPF metaadat-jelentési vagy értékmeghatározási API-kkal, például LocalValueEnumerator. További információért lásd: Függőségi tulajdonság biztonsága.
Írásvédett függőségi tulajdonságok esetén a RegisterReadOnly által visszaadott érték DependencyPropertyKey, és általában nem fogja DependencyPropertyKey-t a public osztály tagjává tenni. Mivel a WPF tulajdonságrendszer nem propagálja a DependencyPropertyKey a kódon kívül, egy írásvédett függőségi tulajdonság nagyobb biztonságot set, mint egy írásvédett függőségi tulajdonság.
Függőségi tulajdonságok és osztálykonstruktorok
A felügyelt kódprogramozásban van egy általános alapelv, amelyet gyakran kódelemzési eszközök kényszerítenek ki, az osztálykonstruktoroknak nem szabad virtuális metódusokat hívniuk. Ennek az az oka, hogy az alapkonstruktorok meghívhatók egy származtatott osztálykonstruktor inicializálása során, és az alapkonstruktor által hívott virtuális metódus a származtatott osztály teljes inicializálása előtt futhat. Ha egy olyan osztályból származik le, amely már a DependencyObject-ból származik, akkor maga a tulajdonságrendszer hív meg és tesz elérhetővé virtuális metódusokat belsőleg. Ezek a virtuális módszerek a WPF tulajdonságrendszer-szolgáltatások részét képezik. A metódusok felülírásával a származtatott osztályok részt vehetnek az értékmeghatározásban. A futtatókörnyezet inicializálásával kapcsolatos lehetséges problémák elkerülése érdekében ne állítson be függőségi tulajdonságértékeket az osztályok konstruktoraiban, hacsak nem követ egy adott konstruktormintát. További információért lásd: Biztonságos konstruktorminták a DependencyObjects számára.
Lásd még
.NET Desktop feedback