Priehľadné okno s Aero Glass efektom v C # .NET WPF - Časť 1
Tentoraz to bude trochu "vyššia dievčenská", pokúsime sa "nahackovat" do systémových prostriedkov operačného systému Windows 10. Všetci iste dobre poznáte Aero Glass dizajn okien, ktoré predstavil Microsoft s príchodom Windows Vista, aby ho zarezal s novými Windows 8/10. Podporu oficiálne odstránil tak z vývojárskych nástrojov (myslím, že od verzie .NET Framework 3.5 nemožno volať DWM pre WinForms, ktoré rozmazané pozadie formulára bežne užívali). Avšak zo mňa neznámych dôvodov stále existuje nezdokumentované API, ktoré toto umožňuje pod Windows 10. My sa k nemu dnes dostaneme a urobíme si pekný priehľadný formulár s efektom rozmazania, ktorý môžeme využiť tak ako napríklad ja v mojej aplikácii: Počasie na desktope - voľne šíriteľná verzia tu:
Čo budeme potrebovať
- Visual Studio 2017 alebo 2019 (v tejto verzii budem vytvárať sprievodca, zmeny oproti verzii 2017 by mali byť len kozmetické)
- Znalosť jazyka C# a Visual Studia
- Pokročilejšie orientáciu v OOP
- Windows 10
Čo sa dnes naučíme
- Prácu s knižnicami a prostriedkami operačného systému
- Nastavenie formulára WPF
- Práca s API operačného systému
- Práca s
Brush
farbami, miešanie a prevod farieb
Založenie nového projektu
Vytvorme nový projekt typu Aplikácia WPF (.NET Framework). V prípade UWP tento postup bohužiaľ nebude fungovať, vzhľadom k predstavenému "Fluent design" u Windows 10 sú priehľadné formuláre riadené striktne OS. Pri strate aktivity okna (keď klikneme napr. Na plochu mimo formulár) sa rozmazaniu vždy vypne a prepne sa do nepriehľadnej farby, čo nie je vždy to, čo potrebujeme.
Design aplikácie
Tu si vystačíme len s oknom s upravenými parametrami, jedným prvkom
<Slider>
a piatimi prvkami <TextBlock>
pre
jednoduché nastavenie a zobrazenie kódu použité farby na formulári.
Nastavenie formulára Window
Je však potrebné dodržať niekoľko pravidiel a odporúčaní:
- Je potrebné nastaviť parameter
AllowsTransparency="True"
, čiže povoliť priehľadnosť formulára. Vďaka tomu môžeme voľne nastavovať transparentnosť pomocouBrush
farby alebo hodnotyOpacity
. - S prvým nastavením sa viaže podmienka kompilátora, ktorá neumožňuje,
aby bolo možné pri
AllowsTransparency="True"
mať štýl zobrazeného okna akýkoľvek iný akoWindowStyle="None"
. Ten je teda nutné nastaviť, ak to nevykoná Visual Studio automaticky za nás (to je veľmi pravdepodobné).WindowStyle
hovorí OS, aké ovládacie prvky budú na oknu vykreslené. V našom prípade to logicky nebudú žiadne, okrem absencia klasickej lišty s názvom aplikácie a obligátnych troch tlačidiel v pravom rohu narazíme na iné problémy s tým spojené:- Pokiaľ si budete chcieť takýto formulár niekam posunúť, tak neuspejete, pretože ho nie je za čo "chytiť". Nižšie ukážem ako toto obmedzenie elegantne a jedným riadkom kódu v Code behind obísť.
- To isté platí pre zmenu rozmeru súčasného okna, na čo ale už bolo
pamätané, a vyriešime to rovno v XAML parametrom
ResizeMode="CanResizeWithGrip"
. Týmto parametrom sa v pravom dolnom rohu formulára vykreslí tri čiarky, za ktoré klikom myši chytíme a formulári môžeme ľubovoľne upravovať rozmery. Decentná, rýchle a elegantné.
- Ďalej môžeme nastaviť
BorderThickness="2"
aBorderBrush="Black"
, čo zobrazí oknu okraje široké 2px v čiernej farbe. Ide ale čisto o estetický detail tak, aby sa okraj okna jasne oddelil od pozadia formulára. - Na rýchle otestovanie, či máme správne zapnutú transparency, môžeme
nastaviť rovno farbu
Background="#7FFFFFFF"
. To znamená bielu farbu s 50% priehľadnosťou.
Na formulár postupne vložíme:
<Grid>
- rozdelený približne na tretiny<Slider>
- s rozsahom0
-255
, ktorý nesmie byť prekročený.<ViewBox>
- roztiahne obsiahnutýTextBlock
tak aby bol stále vo rovnakým pomere ku veľkosti formulára<TextBlock>
- obyčajnýTextBlock
, ktorý bude vypisovať aktuálne farbu v HTML kóde
Kód XAML bude nasledujúci:
<Window x:Name="Okno" x:Class="BluredFormNETF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:BluredFormNETF" mc:Ignorable="d" MouseLeftButtonDown="Window_MouseLeftButtonDown" Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded" AllowsTransparency="True" WindowStyle="None" ResizeMode="CanResizeWithGrip" BorderThickness="2" BorderBrush="Black" Background="#7FFFFFFF"> <Grid > <Grid.RowDefinitions> <RowDefinition Height="1*"/> <RowDefinition Height="1*"/> <RowDefinition Height="1*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> </Grid.ColumnDefinitions> <Slider Grid.Row="0" Grid.Column="0" ValueChanged="Slider_ValueChanged" Maximum="255" SmallChange="1" TickFrequency="10" TickPlacement="BottomRight" Background="#7F2F1E47" Value="125" Grid.ColumnSpan="3" Grid.RowSpan="3"/> <Grid Grid.Row="1" Grid.Column="1"> <Grid.RowDefinitions> <RowDefinition Height="1*"/> <RowDefinition Height="0.4*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="0.4*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> </Grid.ColumnDefinitions> <Viewbox Stretch="Uniform" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="5" VerticalAlignment="Bottom"> <TextBlock Name="barva" Text="{Binding Value, ElementName=SliderValueText}" Foreground="White" FontFamily="Consolas"/> </Viewbox> <Viewbox Stretch="Uniform" Grid.Row="1" Grid.Column="1" VerticalAlignment="Top"> <TextBlock Text="ALPHA" Foreground="White"/> </Viewbox> <Viewbox Stretch="Uniform" Grid.Row="1" Grid.Column="2" VerticalAlignment="Top"> <TextBlock Text=" RED " Foreground="Red"/> </Viewbox> <Viewbox Stretch="Uniform" Grid.Row="1" Grid.Column="3" VerticalAlignment="Top"> <TextBlock Text="GREEN" Foreground="Green"/> </Viewbox> <Viewbox Stretch="Uniform" Grid.Row="1" Grid.Column="4" VerticalAlignment="Top"> <TextBlock Text=" BLUE " Foreground="Blue" /> </Viewbox> </Grid> </Grid> </Window>
Výsledok by mal vyzerať nejako takto:
Brush - Ako funguje jednoduché mixovanie farieb
Než sa vrhneme na Code behind a to na čo netrpezlivo čakáte, tak si v
rýchlosti povieme niečo o triede Brush
. Presnejšie ako pracuje s
farbami a ako jednoducho to využiť pre náš projekt. Vo WPF aj UWP sa už
nepoužíva pôvodné jednoduchá trieda Colors
, ktorá prakticky
umožňovala len obmedzenú prácu s modernými efektmi a preto bola nahradená
podstatne modernejší a flexibilnejší triedou Brushes
. Tá sa
používa kdekoľvek, kde je potrebné povedať kompilátora akú má mať
niečo farbu. Netreba panikáriť, z Colors
si táto trieda
ponechala jednoduché názvoslovie najpoužívanejších farieb, a doplnila ich
o ďalšie efekty ako prechody pod.
Nás pre našu aplikáciu bude zaujímať len ako si obyčajne namiešať vlastnú farbu pomocou základných farieb RGB s doplnkovou hodnotou ALPHA kanálu - čiže hodnotou priehľadnosti. To budeme potrebovať pre nastavenie priehľadnosti okna ďalej v kóde.
Využijeme možnosti jednoducho konvertovať z hexadecimálneho zápisu HTML, ktorý je upravený o Alpha kanál vo formáte tak, ako je naznačené v tabuľke nižšie:
Rozsah farebnej hĺbky je zapísaný hexadecimálne a je teda v rozsahu
0
- 255
pre každý farebný kanál. V príklade je
50% hodnota pre všetky kanály, čo robí približne číslo 127
(7F
).
Toto všetko jednoducho zastrešuje
System.Windows.Media.BrushConverter
:
var converter = new System.Windows.Media.BrushConverter();
Viac ale už v Code behind v druhom diele.