0. Diel WPF - Rýchlosť vykresľovanie
V minulej lekcii, Hrianok notifikácia v C # .NET WPF , sme sa naučili tvoriť hrianok notifikácia.
Ahoj, rozhodol som sa začať s tutoriály pre WPF, pretože mi príde, že je pokročilejší ako Windows Forms, aspoň pokiaľ ide o vykresľovanie. Je tomu preto, že vo WPF sa už nepoužíva GDI a jeho systém spracovania grafiky v procesore, ale sa využíva DirectX3D, čo je bezpochyby veľká výhoda. Už nedochádza k preblikávania pri aktualizácii okna. Ak ste nikdy nerobili vo Windows Forms, tak tieto tutoriály nejspíš moc nepochopíte, pretože tu budem veľa porovnávať WF a WPF a popisovať rozdiely a ako prejsť z WF na WPF.
WPF síce používa jazyk C# rovnako ako WF, ale líšia sa tým, že na nastylování okná používa jazyk XAML, ktorý je podobný HTML kódu.
Jeho najväčšia prednosť vám ukážem na jednoduchom prográmku, ktorý som si nazval pre názornosť HalfHeight ktorý si vytvorím zároveň vo WF i vo WPF.
V tomto "programe" sa nám bude pohybovať obdĺžnik, ktorý zaberá celý form na šírku a polku na výšku. Bude sa pohybovať hore a dole, tým môžeme sledovať rýchlosť vykresľovania.
Zdrojový kód hlavného formu HalfHeight vo WF:
{ public partial class Form1 : Form { // základní graphics formu Graphics g; // vedlejší graphics který neuvidíme Graphics tempGraphics; // bitmapa pro vytvoření vedlejších graphics Bitmap tempBitmap; // čas poslední snímku DateTime lastFrame; // obdelník pro zkoušku vykreslování Rectangle rectangle; // štětec s barvou SolidBrush brush = new SolidBrush(Color.Red); // proměnná zjištující pohyb obdelníku směrem dolů bool IsRectangleMovingDown = true; public Form1() { InitializeComponent(); // vytvoří graphics hlavního formu g = this.CreateGraphics(); // nastaví proměnou DateTime na teď lastFrame = DateTime.Now; // vytvoří nový timer Timer t = new Timer(); // nastaví timer aby se spouštěl každou milisekundu (bude se spouštět méně často, ale menší hodnotu nastavit nelze) t.Interval = 33; // přidá event k timeru t.Tick += new EventHandler(t_Tick); // spustí timer t.Start(); } protected override void OnLoad(EventArgs e) { // vytvoří novou bitmapu s velikostí okna tempBitmap = new Bitmap(this.ClientSize.Width, this.ClientSize.Height); // vytvoří vedlejší graphics podle bitmapy tempGraphics = Graphics.FromImage(tempBitmap); // deklaruje nový obdelník rectangle = new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height / 2); } void t_Tick(object sender, EventArgs e) { // vyčistí vedlejší graphics tempGraphics.Clear(Color.White); // vykreslí obdelník do vedlejších graphics tempGraphics.FillRectangle(brush, rectangle); // vykreslí vedlejší graphics do formu g.DrawImage(tempBitmap, Point.Empty); // pohyb obdelníku nahoru a dolů if (IsRectangleMovingDown) { if (rectangle.Y < this.ClientSize.Height / 2) { rectangle = new Rectangle(rectangle.X, rectangle.Y + 25, rectangle.Width, rectangle.Height); } else { IsRectangleMovingDown = false; } } else { if (rectangle.Y > 0) { rectangle = new Rectangle(rectangle.X, rectangle.Y - 25, rectangle.Width, rectangle.Height); } else { IsRectangleMovingDown = true; } } // přepočítání času TimeSpan elapsed = DateTime.Now - lastFrame; // zobrazí počet uplynulých ms od posledního updatu label1.Text = elapsed.TotalMilliseconds.ToString(); // zapsání nového času lastFrame = DateTime.Now; } } }
Zdrojový kód hlavného formu HalfHeight vo WPF:
XAML časť:
<Window x:Class="HalfHeight_WPF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" WindowState="Maximized" Loaded="Window_Loaded"> <Grid Name="grid"> <Rectangle HorizontalAlignment="Left" Name="rectangle1" Stroke="Black" VerticalAlignment="Top" Fill="Red" Width="100" Height="100" /> <TextBlock HorizontalAlignment="Left" Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" Background="Gray" Margin="12,12,0,0" /> </Grid> </Window>
C# časť:
{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { bool IsRectangleMovingDown = true; DateTime lastFrame; public MainWindow() { InitializeComponent(); lastFrame = DateTime.Now; DispatcherTimer t = new DispatcherTimer(); t.Interval = TimeSpan.FromMilliseconds(1); t.Tick += new EventHandler(t_Tick); t.Start(); } private void Window_Loaded(object sender, RoutedEventArgs e) { rectangle1.Width = grid.ActualWidth; rectangle1.Height = grid.ActualHeight / 2; } void t_Tick(object sender, EventArgs e) { if (IsRectangleMovingDown) { if (rectangle1.Margin.Top < grid.ActualHeight / 2d) { rectangle1.Margin = new Thickness(rectangle1.Margin.Left, rectangle1.Margin.Top + 25, 0, 0); } else { IsRectangleMovingDown = false; } } else { if (rectangle1.Margin.Top > 0) { rectangle1.Margin = new Thickness(rectangle1.Margin.Left, rectangle1.Margin.Top - 25, 0, 0); } else { IsRectangleMovingDown = true; } } TimeSpan elapsed = DateTime.Now - lastFrame; textBlock1.Text = elapsed.TotalMilliseconds.ToString(); lastFrame = DateTime.Now; } } }
Nákupný
Na mojom počítači sa mi ukazoval vo WF čas od posledného obrázka 90 - 110 ms (cca 10 FPS) a vo WPF 10 - 20 ms (cca 50 - 100 FPS).
Vo WF tam bol vidieť jasne trhaný pohyb, zatiaľ čo vo WPF nebol vidieť jediný zásek.
Dúfam, že to postačí ako dôkaz ako rýchlo je WPF schopné vykresľovať narozdiel od WF, zdrojové kódy HalfHeight vo WF aj WPF budú priložené.
V budúcom dieli si ukážeme základné kontrolky WPF.