Rajzolás WPF alkalmazásokban Vizuális programozás Rajzolás WPF alkalmazásokban
2D rajzolás Retained-mode graphics – a WPF gondoskodik a perzisztenciáról Rajzolási lehetőségek - szintek Shapes Drawings & Geometries Visuals Közös eszközök Ecsetek, tollak, Transzformációs objektumok A GDI+-ban immediate mode graphics volt, azaz a programozó kellett gondoskodjon a perzisztenciáról és frissítésről, ld. Eltűnő kép probléma
J.Zs.Cs.: Vizuális programozás (c) 2012 Shapes - Alakzatok Magas szintű, néhány osztály, rengeteg metódus, tulajdonságok, eseménykezelés, input kezelés (egér, billentyűzet) , kényelmes használat, Nagy memóriahasználat, lassú Egy sor szabályos geometriai objektum (Ellipse, Line, Polygon,PolyLine, Rectangle, Path) Megvalósítható: XAML-ben és C#-ban http://msdn.microsoft.com/en-us/library/ms747393.aspx J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 XAML Egyszerűen leírható XAML-ben: <Ellipse Width="40" Height="50" Stroke="Green" StrokeThickness="2" Fill="LightGreen" Canvas.Left="25" Canvas.Top="30" Name="elLomb" MouseDown="elLomb_MouseDown" MouseMove="elLomb_MouseMove" /> J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Double TetőMagasság=30; Rectangle rcHáz = new Rectangle(); rcHáz.Width=110; rcHáz.Height=80; rcHáz.Stroke = Brushes.DarkRed; rcHáz.StrokeThickness = 2; rcHáz.Fill = Brushes.LightCoral; rcHáz.SetValue(Canvas.LeftProperty, (double)(100)); rcHáz.SetValue(Canvas.TopProperty, (double)(100+TetőMagasság)); cvLap.Children.Add(rcHáz); J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 RectangleGeometry LineGeometry EllipseGeometry PathGeometry J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Z sorrend A tárolóra elhelyezett alakzatok között van egy Z-sorrend A később feltett alakzatok elfedhetik a korábban feltett alakzatokat (pl. ha az elsőnek feltett alakzatot átmozgatjuk a másodiknak feltett alakzat pozíciójába, akkor az első a második alá kerül). J.Zs.Cs.: Vizuális programozás (c) 2012
Shapes – Mikor használjuk? Felhasználói interakció szükséges Egér input ToolTip J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Drawings & Geometries System.Windows.Media.Drawing absztrakt osztály leszármazottaival Vékonyabb réteg (ún. pehelysúlyú szolgáltatások) gyorsabb, kisebb erőforrásigény Nincs beépített input kezelés Valamilyen hoszt objektumban kell elhelyezni (pl. DrawingImage, DrawingBrush, DrawingVisual) Több kód szükséges Fontosabb osztályok: GeometryDrawing, ImageDrawing J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Felhasnálói interakció csak jelentős kódolás árán oldható meg Megvalósítható: XAML-ben és C#-ban J.Zs.Cs.: Vizuális programozás (c) 2012
Drawings & Geometries – Mikor használjuk? Felhasználói interakció nem szükséges (bár megoldható) Komplex, vektor alapú grafikus adatmegjelenítés szükséges J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Visuals System.Windows.Media.Visual leszármazottai Legvékonyabb réteg leggyorsabb; csak elemi szolgáltatások, mindenhez meg kell írni a kódot (legtöbb kódolás) Nincs input esemény, felületmenedzser, adatkötés, alacsony szintű megközelítés Fontosabb osztályok: DrawingVisual, Viewport3DVisual, ContainerVisual J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Visuals Legkisebb erőforrásigény Legjobb teljesítmény Valamilyen hoszt objektumban kell elhelyezni (pl. DrawingImage, DrawingBrush, DrawingVisual) Csak C#-ből oldható meg Rajzolási kapcsolatot/eszközkapcsolatot kell létrehozni és megnyitni, majd a rajzolást követően lezárni (using szerkezet használható) J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Visuals Az új objektumot el kell helyezni a logikai és a vizuális fában Át kell definiálni a VisualChildrenCount virtuális tulajdonságot Át kell definiálni a GetVisualChild virtuális metódust Mikor használjuk? Nagy mennyiségű adat gyors megjelenítésére J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Vonalrajzolás - Pen Legtöbbször nem kell közvetlenül előállítani, az egyes alakzatok vonaltulajdonságainak megadásával definiálhatjuk jellemzőit J.Zs.Cs.: Vizuális programozás (c) 2012
Vonaljellemzők megadása <Line Stroke="Black" StrokeEndLineCap="Triangle" StrokeStartLineCap="Round" StrokeThickness="15" X1="30" Y1="30" X2="100" Y2="30" /> <Line Stroke="Black" StrokeThickness="10" StrokeDashArray="2 0.4 0.4 0.4" X1="130" Y1="30" X2="250" Y2="30" /> A szaggatott vonalat a StrokeDashArray segítségével definiáljuk. A megadott minta fog ismétlődni. Itt 2 egység vonal 0.4 egység szünet, 0.4 egység rövid vonal, 0,4 egység szünet. A tényleges hosszúság a vonalvastagság függvénye (2x10=20 pont). J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Brush SolidColorBrush LinearGradientBrush RadialGradientBrush ImageBrush DrawingBrush – kifestés egy olyan objektummal, ami a Drawing leszármazottja VisualBrush - kifestés egy olyan objektummal, ami a Visual leszármazottja J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Kifestés – Brush Egyenletes kifestés és sugár irányú gradiens színváltós kifestés beállítása J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Kifestés – Brush <Ellipse Fill="#FFC42D2D" Canvas.Left="10" Canvas.Top="100" Width="60" Height="60" /> <Ellipse Canvas.Left="100" Canvas.Top="100" Width="60" Height="60"> <Ellipse.Fill> <RadialGradientBrush> <GradientStop Color="Blue" Offset="0" /> <GradientStop Color="Red" Offset="1" /> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Transformations TranslateTransform RotateTransform ScaleTransform SkewTransform MatrixTransform TransformGroup Demo A transzformációt követően is tárolva marad az eredeti helyzet, és ha megadunk egy új transzformációt, akkor az az eredetei helyzethez képes értelmeződik. Ld. Példaprogram: hajtsuk végre egymás után az eltolást és a forgatást. http://www.codeproject.com/Articles/14895/WPF-Tutorial-Part-1-Transformations http://msdn.microsoft.com/en-us/library/ms750596.aspx J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 SkewTransform http://msdn.microsoft.com/en-us/library/ms746708.aspx J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 MatrixTransform M11 M12 0 M21 M22 0 OfX OfY 1 X' = X*M11 + Y*M21 + OfX Y' = X*M12 + Y*M22 + OfY J.Zs.Cs.: Vizuális programozás (c) 2012
WPF animációk
J.Zs.Cs.: Vizuális programozás (c) 2012 Animáció using System.Windows.Media.Animation; Vezérlő egy vagy több tulajdonságának változtatása DependencyProperty kell legyen, pl. WidthProperty HeightProperty Az adott DependencyProperty egy hagyományos tulajdonságot képvisel csak olvasható módon J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Animáció típusok Lineáris (egyenletes) változtatás két érték között: AdattípusAnimation (DoubleAnimation, ColorAnimation, ByteAnimation, stb.) Útvonal alapú: AdattípusAnimationUsingPath (DoubleAnimationUsingPath) Előredefiniált értéksor váltogatása: AdattípusAnimationUsingKeyFrames J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Lineáris animáció Méretváltoztató animáció Ha az egeret a kép fölé visszük, kitölti a piros vonallal megrajzolt keretet DoubleAnimation From To Duration Vezérlő.BeginAnimation J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 A felület J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Megvalósítás TimeSpan ts = TimeSpan.FromMilliseconds(500); DoubleAnimation da=new DoubleAnimation(); da.From = KépSzélesség; da.To = KépSzélesség + dSz; da.Duration=new Duration(ts); DoubleAnimation db=new DoubleAnimation(); db.From = KépMagasság; db.To = KépMagasság + dM; db.Duration = new Duration(ts); imKép.BeginAnimation(WidthProperty,da); imKép.BeginAnimation(HeightProperty,db); private void imKép_MouseEnter(object sender, MouseEventArgs e) { // A vízszintes méretváltoztatást leíró animáció objektum. DoubleAnimation da=new DoubleAnimation(); // Kezdőméret. da.From = KépSzélesség; // Végső méret. da.To = KépSzélesség + dSz; // Az animáció időtartama. da.Duration=new Duration(ts); // A függőleges méretváltoztatást leíró animáció objektum. DoubleAnimation db = new DoubleAnimation(); db.From = KépMagasság; db.To = KépMagasság + dM; db.Duration = new Duration(ts); // A két animáció elindítása. imKép.BeginAnimation(WidthProperty,da); imKép.BeginAnimation(HeightProperty,db); } J.Zs.Cs.: Vizuális programozás (c) 2012
Beállítási lehetőségek From To By Duration AccelerationRatio DecelerationRatio SpeedRatio AutoReverse BeginTime RepeatBehavior FillBehavior Esemény: Completed By - ennyivel változik a kezdőérték AutoReverse – a végrehajtás után csinálja meg visszafele is BeginTime – mennyi idő múlva kezdődjön – alap 0 (késleltetés) FillBehavior RepeatBehavior – ismétlődjön-e (db, végtelen, idő) J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Demo KepMeretvaltoztato TeglalapMeretvalto J.Zs.Cs.: Vizuális programozás (c) 2012
Útvonal alapú animáció J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 A felület <DockPanel> <ToolBar DockPanel.Dock="Top" Height="30" Name="toEszköztár"> <Button Name="btIndít" Click="btIndít_Click" Content="Indít"/> </ToolBar> <Canvas Name="cvLap" DockPanel.Dock="Top"> <Rectangle Name="rcNégyzet" Width="10" Fill="IndianRed" Height="10" /> </Canvas> </DockPanel> J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Az útvonal megadása Útvonalgeometria (PathGeometry) Útvonalalak (PathFigure) Szegmens (ArcSegment,BezierSegment,PolyBezierSegment, LineSegment, PolyLineSegment, PolyQuadraticBezierSegment, QuadraticBezierSegment) Szegmens … Útvonalalak … … J.Zs.Cs.: Vizuális programozás (c) 2012
J.Zs.Cs.: Vizuális programozás (c) 2012 Animáció Külön az x és y koordinátára DoubleAnimationUsingPath daxAnimáció = new DoubleAnimationUsingPath(); daxAnimáció.PathGeometry = pgÚtvonal; daxAnimáció.Duration = TimeSpan.FromSeconds(10); daxAnimáció.Source = PathAnimationSource.X; daxAnimáció.AutoReverse = true; rcNégyzet.BeginAnimation(Canvas.TopProperty, daxAnimáció); J.Zs.Cs.: Vizuális programozás (c) 2012
Előredefiniált értéksor Demo J.Zs.Cs.: Vizuális programozás (c) 2012