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.
Ez a témakör azt ismerteti, hogyan lehet hatékonyan használni és létrehozni Freezable objektumokat, amelyek olyan speciális funkciókat biztosítanak, amelyek segíthetnek az alkalmazások teljesítményének javításában. Fagyasztható objektumok például a kefék, írószerek, átalakítások, geometriák és animációk.
Mi az a fagyasztható dolog?
A Freezable egy speciális objektumtípus, amelynek két állapota van: unfrozen és frozen. A feloldáskor úgy tűnik, hogy egy Freezable úgy viselkedik, mint bármely más objektum. Fagyasztáskor a Freezable már nem módosítható.
A Freezable egy Changed eseményt biztosít, amely értesíti a megfigyelőket az objektum módosításairól. A Freezable befagyasztása javíthatja a teljesítményét, mivel már nem kell erőforrásokat költenie a változásértesítésekre. A fagyasztott Freezable a szálak között is megosztható, míg a nem fagyott Freezable nem.
Bár a Freezable osztály számos alkalmazással rendelkezik, a Windows Presentation Foundation (WPF) legtöbb Freezable objektuma a grafikus alrendszerhez kapcsolódik.
A Freezable osztály megkönnyíti bizonyos grafikus rendszerobjektumok használatát, és javíthatja az alkalmazás teljesítményét. A Freezable öröklő típusok közé tartoznak például a Brush, Transformés Geometry osztályok. Mivel nem felügyelt erőforrásokat tartalmaznak, a rendszernek módosítania kell ezeket az objektumokat, majd frissítenie kell a megfelelő nem felügyelt erőforrásokat az eredeti objektum módosításakor. Még ha nem is módosítja a grafikus rendszer objektumait, a rendszernek továbbra is az objektum figyelésére kell fordítania egyes erőforrásait, ha mégis módosítja.
Tegyük fel például, hogy létrehoz egy SolidColorBrush ecsetet, és egy gomb hátterének festésére használja.
Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
myButton.Background = myBrush;
Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)
myButton.Background = myBrush
A gomb megjelenítésekor a WPF grafikus alrendszer a megadott információk alapján képpontok egy csoportját festi egy gomb megjelenésének létrehozásához. Bár egyszínű kefével írta le, hogyan kell festeni a gombot, az egyszínű kefe valójában nem teszi meg a festést. A grafikus rendszer gyors, alacsony szintű objektumokat hoz létre a gombhoz és az ecsethez, és ezek azok az objektumok, amelyek ténylegesen megjelennek a képernyőn.
Ha módosítaná az ecsetet, azokat az alacsony szintű objektumokat újra kellene létrehozni. A "fagyasztható" osztály az, ami lehetővé teszi az ecset számára, hogy megtalálja a hozzá tartozó generált, alacsony szintű objektumokat, és frissítse ezeket, amikor változik. Ha ez a képesség engedélyezve van, a kefe "felolvadtnak" van mondva.
A Freezable Freeze eljárása lehetővé teszi, hogy letiltsuk az önfrissítési képességet. Ezzel a módszerrel az ecsetet "lefagyasztottá", vagy nem módosíthatóvá teheti.
Megjegyzés:
Nem minden fagyasztható objektum fagyasztható. Ha nem szeretne InvalidOperationExceptiondobni, ellenőrizze a fagyasztható objektum CanFreeze tulajdonságának értékét, és állapítsa meg, hogy le lehet-e fagyasztani, mielőtt megkísérelné lefagyasztani.
if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
}
If myBrush.CanFreeze Then
' Makes the brush unmodifiable.
myBrush.Freeze()
End If
Ha már nem kell módosítania egy szabadható objektumot, annak megfagyasztása teljesítménybeli előnyöket biztosít. Ha ebben a példában lefagyasztaná az ecsetet, a grafikus rendszernek már nem kellene figyelnie az esetleges változásokat. A grafikus rendszer más optimalizálásokat is végezhet, mert tudja, hogy az ecset nem változik.
Megjegyzés:
Az egyszerűség kedvéért a fagyasztható objektumok fagymentesek maradnak, hacsak nem fagyasztja le őket kifejezetten.
Freezables használata
A nem fagyasztható objektumok használata olyan, mint bármely más típusú objektum használata. Az alábbi példában egy SolidColorBrush színe sárgáról pirosra változik, miután a gomb háttérszíneként használták fel. A grafikus rendszer a színfalak mögött dolgozik, hogy a képernyő következő frissítésekor automatikusan sárgáról pirosra módosítsa a gombot.
Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
myButton.Background = myBrush;
// Changes the button's background to red.
myBrush.Color = Colors.Red;
Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)
myButton.Background = myBrush
' Changes the button's background to red.
myBrush.Color = Colors.Red
Egy fagyasztható tárgy fagyasztása
A Freezable nem módosíthatóvá tétele érdekében meghívja annak Freeze metódusát. Egy, a fagyasztható objektumokat tartalmazó objektum lefagyasztásakor ezek az objektumok is lefagynak. Ha például lefagy egy PathGeometry, a benne szereplő adatok és szegmensek is le lesznek fagyasztva.
A fagyasztható nem lehet fagyasztani, ha az alábbiak bármelyike igaz:
Animált vagy adathoz kötött tulajdonságokkal rendelkezik.
Dinamikus erőforrás által beállított tulajdonságokkal rendelkezik. (A dinamikus erőforrásokról további információt a XAML-erőforrások talál.)
Olyan Freezable alobjektumokat tartalmaz, amelyek nem fagyaszthatók le.
Ha ezek a feltételek hamisak, és nem áll szándékában módosítani a Freezable-t, akkor le kell fagyasztania a korábban ismertetett teljesítménybeli előnyök eléréséhez.
Ha meghívja egy fagyasztható objektum Freeze metódusát, az már nem módosítható. A fagyasztott objektumok módosításának megkísérlése InvalidOperationException okoz. A következő kód kivételt jelez, mert a fagyasztás után megpróbáljuk módosítani az ecsetet.
Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
}
myButton.Background = myBrush;
try {
// Throws an InvalidOperationException, because the brush is frozen.
myBrush.Color = Colors.Red;
}catch(InvalidOperationException ex)
{
MessageBox.Show("Invalid operation: " + ex.ToString());
}
Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)
If myBrush.CanFreeze Then
' Makes the brush unmodifiable.
myBrush.Freeze()
End If
myButton.Background = myBrush
Try
' Throws an InvalidOperationException, because the brush is frozen.
myBrush.Color = Colors.Red
Catch ex As InvalidOperationException
MessageBox.Show("Invalid operation: " & ex.ToString())
End Try
A kivétel elkerülése érdekében a IsFrozen metódussal megállapíthatja, hogy egy Freezable le van-e fagyasztva.
Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
}
myButton.Background = myBrush;
if (myBrush.IsFrozen) // Evaluates to true.
{
// If the brush is frozen, create a clone and
// modify the clone.
SolidColorBrush myBrushClone = myBrush.Clone();
myBrushClone.Color = Colors.Red;
myButton.Background = myBrushClone;
}
else
{
// If the brush is not frozen,
// it can be modified directly.
myBrush.Color = Colors.Red;
}
Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)
If myBrush.CanFreeze Then
' Makes the brush unmodifiable.
myBrush.Freeze()
End If
myButton.Background = myBrush
If myBrush.IsFrozen Then ' Evaluates to true.
' If the brush is frozen, create a clone and
' modify the clone.
Dim myBrushClone As SolidColorBrush = myBrush.Clone()
myBrushClone.Color = Colors.Red
myButton.Background = myBrushClone
Else
' If the brush is not frozen,
' it can be modified directly.
myBrush.Color = Colors.Red
End If
Az előző kód példában egy módosítható másolat készült egy fagyasztott objektumról a Clone metódus használatával. A következő szakasz részletesebben ismerteti a klónozást.
Megjegyzés:
Mivel a fagyasztott fagyasztható nem animálható, az animációs rendszer automatikusan módosítható klónokat hoz létre a fagyasztott Freezable objektumokból, amikor Storyboard-gyel próbálják őket animálni. A klónozás által okozott teljesítményterhelés megszüntetéséhez hagyja az objektumot befagyasztás nélkül, ha animálni szeretné. A storyboardokkal való animálásról további információt a Storyboards overviewcímű cikkben talál.
Lefagyás a Korrektúra alkalmazásból
A megjelölésben deklarált Freezable objektum lezárása a PresentationOptions:Freeze attribútummal történik. Az alábbi példában a SolidColorBrush laperőforrásként deklarálva lesz, és le van fagyasztva. Ezután egy gomb hátterének beállítására szolgál.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="PresentationOptions">
<Page.Resources>
<!-- This resource is frozen. -->
<SolidColorBrush
x:Key="MyBrush"
PresentationOptions:Freeze="True"
Color="Red" />
</Page.Resources>
<StackPanel>
<Button Content="A Button"
Background="{StaticResource MyBrush}">
</Button>
</StackPanel>
</Page>
A Freeze attribútum használatához hozzá kell rendelnie a prezentációs lehetőségek névteréhez: http://schemas.microsoft.com/winfx/2006/xaml/presentation/options.
PresentationOptions a névtér leképezéséhez javasolt előtag:
xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
Mivel nem minden XAML-olvasó ismeri fel ezt az attribútumot, javasoljuk, hogy az mc:Ignorable Attribútum használatával jelölje meg a PresentationOptions:Freeze attribútumot figyelmen kívül hagyhatóként:
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="PresentationOptions"
További információ: mc:Ignorable Attribute oldalon.
"Feloldani egy fagyaszthatót"
A fagyasztás után a Freezable soha nem lehet módosítani vagy feloldani; a Clone vagy a CloneCurrentValue metódussal azonban létrehozhat egy feloldatlan klónt.
A következő példában a gomb hátterét egy kefével állítja be, és az ecset ezután le van fagyasztva. A Clone módszerrel a keféről készült fagymentes másolat készül. A klón módosul, és a gomb hátterének sárga színről pirosra való módosítására szolgál.
Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
// Freezing a Freezable before it provides
// performance improvements if you don't
// intend on modifying it.
if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
}
myButton.Background = myBrush;
// If you need to modify a frozen brush,
// the Clone method can be used to
// create a modifiable copy.
SolidColorBrush myBrushClone = myBrush.Clone();
// Changing myBrushClone does not change
// the color of myButton, because its
// background is still set by myBrush.
myBrushClone.Color = Colors.Red;
// Replacing myBrush with myBrushClone
// makes the button change to red.
myButton.Background = myBrushClone;
Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)
' Freezing a Freezable before it provides
' performance improvements if you don't
' intend on modifying it.
If myBrush.CanFreeze Then
' Makes the brush unmodifiable.
myBrush.Freeze()
End If
myButton.Background = myBrush
' If you need to modify a frozen brush,
' the Clone method can be used to
' create a modifiable copy.
Dim myBrushClone As SolidColorBrush = myBrush.Clone()
' Changing myBrushClone does not change
' the color of myButton, because its
' background is still set by myBrush.
myBrushClone.Color = Colors.Red
' Replacing myBrush with myBrushClone
' makes the button change to red.
myButton.Background = myBrushClone
Megjegyzés:
Függetlenül attól, hogy melyik klónmódszert használja, az animációk soha nem másolódnak át az új Freezable-ba.
A Clone és CloneCurrentValue metódusok a fagyasztható objektumok mély másolatait készítik. Ha a fagyasztható más fagyasztható objektumokat is tartalmaz, klónozzák és módosíthatóvá teszik őket. Ha például klónoz egy befagyasztott PathGeometry, hogy módosítható legyen, a benne lévő számok és szegmensek is másolódnak és módosíthatóvá lesznek.
Saját fagyasztható osztály létrehozása
A Freezable-ból leszármazó osztály a következő funkciókat nyeri el.
Különleges állapotok: írásvédett (fagyasztott) és írható állapot.
Szálbiztonság: egy fagyasztott Freezable megosztható a szálak között.
Részletes változásértesítés: Más DependencyObject-októl eltérően a Szabadon fagyasztható objektumok változásértesítést biztosítanak, amikor a tulajdonságok részértékei megváltoznak.
Egyszerű klónozás: a Fagyasztható osztály már számos olyan módszert implementált, amelyek mély klónokat hoznak létre.
A Freezable a DependencyObjecttípusa, ezért a függőségi tulajdonságrendszert használja. Az osztálytulajdonságoknak nem kell függőségi tulajdonságoknak lenniük, de a függőségi tulajdonságok használata csökkenti az írandó kód mennyiségét, mivel a Freezable osztályt a függőségi tulajdonságok szem előtt tartásával tervezték. A függőségi tulajdonságrendszerről további információt a Függőség tulajdonságainak áttekintésecímű témakörben talál.
Minden Freezable alosztálynak felül kell írnia a CreateInstanceCore metódust. Ha az osztály függőségi tulajdonságokat használ az összes adatához, befejeződött.
Ha az osztály nem függőségi tulajdonságadat-tagokat tartalmaz, felül kell bírálnia a következő metódusokat is:
A következő szabályokat is be kell tartania a nem függőségi tulajdonságokat tartalmazó adattagok elérésére és írására:
Minden olyan API elején, amely nem függőségi tulajdonságadat-tagokat olvas be, hívja meg a ReadPreamble metódust.
Minden olyan API elején, amely nem függőségi tulajdonságadat-tagokat ír, hívja meg a WritePreamble metódust. (Miután az WritePreamble-t meghívta egy API-ban, ha nem függőségi tulajdonságadat-tagokat is olvas, akkor nem szükséges további hívást kezdeményeznie a ReadPreamble-re.)
Hívja meg a WritePostscript metódust, mielőtt kilép a nem függőségi tulajdonságadat-tagoknak írt metódusok közül.
Ha az osztály olyan nem függőségi tulajdonságú adattagokat tartalmaz, amelyek DependencyObject objektumok, akkor is meg kell hívnia a OnFreezablePropertyChanged metódust minden alkalommal, amikor módosítja az egyik értéküket, még akkor is, ha a tagot nullértékre állítja.
Megjegyzés:
Nagyon fontos, hogy minden Freezable metódust, amelyet felülír, az alapimplementáció hívásával kezdjen.
Egy példa egyéni Freezable osztályra: lásd a Egyéni animációs minta.
Lásd még
- Freezable
- egyéni animációs minta
- függőség tulajdonságainak áttekintése
- egyéni függőségi tulajdonságok
.NET Desktop feedback