уторак, 28. новембар 2017.

Rad sa WPF prozorima

Ukoliko niste pročitali post “Uvod u WPF – Windows Presentation Foundation“ savetujem vam da to obavezno uradite i steknete neki uvid u WPF; pre nego što pristupite praktičnoj primeni. Ali nemojte dozvoliti sebi da vas to obeshrabri. Učenje WPF shvatite više kao igranje, jer je zaista interesantno šta sve za razliku od Windows Forms možete da radite sa WPF kontrolama. Sve ono što vas je kočilo kod Windows Forms kontrola da napravite, u WPF je to moguće stavljanjem WPF kontrola u WPF kontrole i kombinovanje istih da rade kao jedna. Pitanje je samo koliko ima nešto smisla kombinovati ili ne. Znači mogućnosti su ono što vam treba biti motivacija. Ja sam svestan da čak i danas postoji mnogo hobista a ne programera koji i dalje ne žele da pređu sa Windows Forms na WPF, ali to više nije ni smešno. Neki to rade zato što im je računar previše star dok drugi jednostavno smatraju učenje XAML uz C# komplikovanim. XAML vam jednostavno olakšava linije i linije code-a, vreme i na jednostavan način povećava kreativnost. Da ne spominjem da vi većinu XAML code-a možete da kreirate podešavanjem svojstava u Properties upotrebom miša. Vaše WPF kontrole naravno možete obogatiti i već napisanim stilovima, animacijama i čime god vi želite, stime da vremenom skupljate i čuvate XAML code koji možete koristiti u više vaših aplikacija. Ali uzmite u obzir da nešto što ste pravili u Windows 7, npr. stil za ListBox kontrolu, neće biti isto transparentan na Windows 10. Ponekad će te u vašim stilovima i šablonima trebati promeniti i prilagoditi novijim operativnim sistemima. Iz tog razloga ukoliko pravite WPF aplikaciju u komercijalne svrhe, morate testirati vašu WPF aplikaciju na više računara, Windows operativnih sistema i korigovati razliku. Ali takođe u dokumentaciji morate navesti za koji operativni sistem je pravljena vaša WPF aplikacija, da ukoliko izađe sledeća verzija Windows-a i vaša aplikacija na njemu ne izgleda baš kao što treba da izgleda, vi ne snosite nikakvu odgovornost.   


( Pravljenje WPF aplikacija je kreativnost i igra ) 

Razlike između WPF i Windows Forms su pre svega što WPF omogućava da pravite mnogo robusnije, bolje i lepše prozore. Početnike najviše zbunjuje što pozicioniranje kontrola je u WPF totalno drugačije i zavisi od panela koji su ne vizualni ali omogućavaju automatsku promenu veličine svih kontrola u njima prilikom promene veličine prozora. Tačno je da za mnogo stvari koje ste radili u Windows Forms, to neće raditi na isti način. Ali će raditi na drugi način, često i bolji ili uopšte neće raditi. Poznato je da WPF aplikacije često imaju svoj vlastiti dizajn i da su često okrenute svom vlastitom šarenilu. Čak što više to se i traži od WPF aplikacija, iako ne treba preterivati. Međutim, postavlja se pitanje koliko je to poželjno s obzirom da nas praksa uči da boje prozora treba da kontroliše sam sistem i da korisnik kroz Windows operativni sistem treba da odredi izborom Windows teme kako će i prozori u vašim WPF aplikacijama biti obojeni. Rešenje je da u svojim WPF aplikacijama omogućite kroz opcije vaše aplikacije i takvu mogućnost. Visual Studio .Net je na primer takođe WPF aplikacija koja deli svoj dizajn na Color Theme kao što su Dark, Blue ili Light. Međutim vi možete pronaći mnoštvo kolor tema za Visual Studio .Net na Internet-u i njih koristiti. Npr. pogledajte moje video tutorijale za osnove C# i videćete da se u njima koristi ne standardna Visual Studio .Net kolor tema. Znači i vi možete omogućiti u vašim WPF aplikacijama da korisnici vaše WPF aplikacije koriste i teme za vašu aplikaciju. Imajte samo u vidu da vaše WPF aplikacije mogu koristiti i slabovidi korisnici i oni koji ne vide sve boje, i bilo bi poželjno omogućiti i njima neku temu. Dok učite dajte sebi slobodu i sa bojama i sa oblicima prozora kako samo vaša mašta može učiniti. Ali samo dok učite WPF; koristite sve boje; poenta je da uživate u vlastitoj kreativnosti. Što više budete eksperimentisali; vaše WPF aplikacije će biti bolje. Krenimo prvo od WPF prozora praktičnim primerima.

Šta je ResizeMode svojstvo i kako ga podesiti?


Prva stvar kod WPF prozora koju trebate podesiti jeste ResizeMode. Ovo svojstvo se nalazi u System.Windows.ResizeMode imenskom prostoru. Ono može imati 4 stanja.

  • No Resize – ne možete menjati veličinu prozora. Maximize i Minimize kontrolna dugmad se ne prikazuju.

  • CanMinimize – možete samo minimizovati prozor. Maximize i Minimize kontrolna dugmad se prikazuju ali Maximize kontrolno dugme nije dostupno.

  • CanResize – imate potpunu mogućnost da menjate veličinu prozora, uključujući i mogućnost skrolovanja. Sva kontrolna dugmad su prikazana i omogućena. Ovo svojstvo je podešeno kao default za sve WPF prozore.

  • CanResizeWithGrip – ima potpuno svu mogućnost kao i CanResize, samo što dadaje mogućnost menjanja veličine prozora u donji desni ugao.


Pogledajte sledeći XAML i C# code primera kako se koristi ResizeMode svojstvo. Obratite pažnju da u vašim WPF aplikacijama jednostavno možete podesiti svojstvo ResizeMode u prozoru Properties, Visual Studio .Net-a ili direktno u XAML code-u što ovde nije slučaj. Promena ResizeMode svojstva je ovde omogućeno kodiranjem u C# iz logičkih razloga.

<Window x:Class="ResizeModeExample.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:ResizeModeExample"
        mc:Ignorable="d"
        Title="ResizeMode Example" Height="350" Width="525"
        Background="Blue"
        BorderBrush="GreenYellow"
        BorderThickness="30">
   
    <Grid>
        <Button x:Name="btnCanMinimize" Content="ResizeMode = CanMinimize" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="200" Click="btnCanMinimize_Click"/>
        <Button x:Name="btnNoResize" Content="ResizeMode = NoResize" HorizontalAlignment="Left" Margin="10,34,0,0" VerticalAlignment="Top" Width="200" Click="btnNoResize_Click"/>
        <Button x:Name="btnCanResize" Content="ResizeMode = CanResize" HorizontalAlignment="Left" Margin="10,57,0,0" VerticalAlignment="Top" Width="200" Click="btnCanResize_Click"/>
        <Button x:Name="btnCanResizeWithGrip" Content="ResizeMode = CanResizeWithGrip" HorizontalAlignment="Left" Margin="10,81,0,0" VerticalAlignment="Top" Width="200" Click="btnCanResizeWithGrip_Click"/>


    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ResizeModeExample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnCanMinimize_Click(object sender, RoutedEventArgs e)
        {
            this.ResizeMode = ResizeMode.CanMinimize;

        }

        private void btnNoResize_Click(object sender, RoutedEventArgs e)
        {
            this.ResizeMode = ResizeMode.NoResize;

        }

        private void btnCanResize_Click(object sender, RoutedEventArgs e)
        {
            this.ResizeMode = ResizeMode.CanResize;

        }

        private void btnCanResizeWithGrip_Click(object sender, RoutedEventArgs e)
        {
            this.ResizeMode = ResizeMode.CanResizeWithGrip;

        }
    }
}

Kako radi i kako izgleda ova WPF aplikacija, najbolje da pogledate u video-u:


( WPF - Windows Presentation Foundation - 2#. ResizeMode )

Šta je WindowStyle svojstvo i kako ga podesiti?

WindowStyle svojstvo WPF prozora je zaduženo za granični stil border WPF prozora. Ovo svojstvo možete podesiti preko Properties prozora Visual Studio .Net-a, direktno u XAML code-u ili sa C# code-om. WindowStyle svojstvo se nalazi u System.Window.WindowStyle imenskom prostoru. Ovaj stil može biti podešen na:

  • None – prozor neće imati Title Toolbar niti kontrolnu dugmad.

  • SingleBorderWindow – prozor će imati i Title Toolbar i kontrolnu dugmad. Takođe je default.

  • ThreeDBorderWindow – prozor će biti identičan SingleBorderWindow-u samo što je trodimenzionalan. Razliku nećete primetiti jer novi operativni sistemi koriste trodimenzionalno iscrtavanje prozora.  

  • ToolWindow – prozor će imati Title Toolbar ali samo Close kontrolno dugme.

 Pogledajte sledeći primer.

<Window x:Class="WindowStyleExample.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:WindowStyleExample"
        mc:Ignorable="d"
        Title="WindowStyle Example" Height="350" Width="525"
        Background="Blue"
        BorderBrush="GreenYellow"
        BorderThickness="30">
   
    <Grid x:Name="windowstyle">
        <Button x:Name="btnSingleBorderWindow" Content="WindowStyle = SingleBorderWindow" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="250" Click="btnSingleBorderWindow_Click"/>
        <Button x:Name="btnNone" Content="WindowStyle = None" HorizontalAlignment="Left" Margin="10,34,0,0" VerticalAlignment="Top" Width="250" Click="btnNone_Click" />
        <Button x:Name="btnToolWindow" Content="WindowStyle = ToolWindow" HorizontalAlignment="Left" Margin="10,57,0,0" VerticalAlignment="Top" Click="btnToolWindow_Click" Width="250"/>
        <Button x:Name="btnThreeDBorderWindow" Content="WindowStyle = ThreeDBorderWindow" HorizontalAlignment="Left" Margin="10,81,0,0" VerticalAlignment="Top" Width="250" Click="btnThreeDBorderWindow_Click"/>

    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WindowStyleExample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnNone_Click(object sender, RoutedEventArgs e)
        {
            this.WindowStyle = WindowStyle.None;

        }

        private void btnToolWindow_Click(object sender, RoutedEventArgs e)
        {
            this.WindowStyle = WindowStyle.ToolWindow;

        }

        private void btnThreeDBorderWindow_Click(object sender, RoutedEventArgs e)
        {
            this.WindowStyle = WindowStyle.ThreeDBorderWindow;

        }

        private void btnSingleBorderWindow_Click(object sender, RoutedEventArgs e)
        {
            this.WindowStyle = WindowStyle.SingleBorderWindow;

        }
    }
}  

Kako radi i kako izgleda ova WPF aplikacija, najbolje da pogledate u video-u:


( WPF - Windows Presentation Foundation - 3#. WindowStyle )

Kako da pozovem iz jednog WPF prozora drugi?

Mislim da je to najčešće pitanje koje početnici postavljaju kad uče WPF. Jednostavno postoje dve vrste WPF prozora koje možete praviti ili pozivati. Jedan način je pozivanje uobičajenog WPF prozora, dok je drugi pozivanje WPF Dialog prozora. Razlika je u tome što kod WPF Dialog prozora ne možete da koristite vaš prethodni prozor dok ne završite vaš rad u WPF Dialog prozoru i zatvorite isti. Da li je vaš WPF prozor uobičajeni prozor ili WPF Dialog prozor to isključivo zavisi na koji način se poziva WPF prozor. Pogledajte sledeći primer gde su dodate neke stvari ali suština je u C# code-u gde se pozivaju WPF prozori.

<Window x:Class="HowtoCallAnotherWindow.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:HowtoCallAnotherWindow"
        mc:Ignorable="d"
        Title="First Window" Height="350" Width="525"
        BorderBrush="Red"
        BorderThickness="30"
        Background="Purple">
    <Grid>
        <Button x:Name="btnNewWindow" Content="New Window" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="200" Click="btnNewWindow_Click"/>
        <Button x:Name="btnNewDialogWindow" Content="btnNewDialogWindow" HorizontalAlignment="Left" Margin="10,34,0,0" VerticalAlignment="Top" Width="200" Click="btnNewDialogWindow_Click"/>
        <TextBlock x:Name="txbTextBox" HorizontalAlignment="Left" Margin="10,163,0,0" TextWrapping="Wrap" Text="This is text from the First Window!" VerticalAlignment="Top" FontSize="30" Foreground="Green"/>

    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace HowtoCallAnotherWindow
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnNewWindow_Click(object sender, RoutedEventArgs e)
        {
            SecondWindow newWindow = new SecondWindow();
            newWindow.Show();

            newWindow.btnOk.IsEnabled = false;
            newWindow.btnCancel.IsEnabled = false;
            txbTextBox.Text = newWindow.txbText.Text;

        }

        private void btnNewDialogWindow_Click(object sender, RoutedEventArgs e)
        {
            SecondWindow newWindow = new SecondWindow();
            bool? result = newWindow.ShowDialog();

            if (result == true)
            {
                txbTextBox.Text = "You pressed Ok button!";

            }
            else
            {
                txbTextBox.Text = "You pressed Cancel button!";

            }
        }
    }
}

<Window x:Class="HowtoCallAnotherWindow.SecondWindow"
        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:HowtoCallAnotherWindow"
        mc:Ignorable="d"
        Title="Second Window" Height="300" Width="300"
        Background="Blue">
    <Grid>
        <TextBlock x:Name="txbText" HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="This is text from the second window!" VerticalAlignment="Top" FontSize="30" Foreground="Yellow"/>
        <Button x:Name="btnOk" Content="Ok" HorizontalAlignment="Left" Margin="10,241,0,0" VerticalAlignment="Top" Width="75" Click="btnOk_Click"/>
        <Button x:Name="btnCancel" Content="Cancel" HorizontalAlignment="Left" Margin="209,241,0,0" VerticalAlignment="Top" Width="75" Click="btnCancel_Click"/>

    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace HowtoCallAnotherWindow
{
    /// <summary>
    /// Interaction logic for SecondWindow.xaml
    /// </summary>
    public partial class SecondWindow : Window
    {
        public SecondWindow()
        {
            InitializeComponent();
        }

        private void btnOk_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;

        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;

        }
    }
}

Kako radi i kako izgleda ova WPF aplikacija, najbolje da pogledate u video-u:


( WPF - Windows Presentation Foundation - 4#. How to Call Another Window )

Šta je WindowStartUpLocation svojstvo i kako ga podesiti?

Videli kako se poziva WPF prozor ali to vam neće biti dovoljno. Kad god pozivate WPF prozor trebate odrediti u kom delu ekrana će se on prikazivati. Za tu svrhu koristimo WindowStartUpLocation svojstvo koje se nalazi u System.Window.WindowStartUpLocation imenskom prostoru. WPF prozor koji pozivate možete pozicionirati na ekranu na 3 načina:
  • CenterScreen – pozicionira WPF prozor na centar ekrana.

  • CenterOwner – pozicionira WPF prozor na centar WPF prozora koji ga poziva.

  • Manual – pozicionira WPF prozor prema gornjem i levom uglu koordinata ekrana na koji ga podesite. Inače ovo je default svojstvo.

Pogledajte sledeći primer.

<Window x:Class="WindowStartupLocation.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:WindowStartupLocation"
        mc:Ignorable="d"
        Title="WindowStartupLocation" Height="350" Width="525"
        BorderBrush="Maroon"
        BorderThickness="30"
        Background="DarkOrange">
   
    <Grid>
        <Button x:Name="btnCenterOwner" Content="WindowStartupLocation = CenterOwner" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="300" Click="btnCenterOwner_Click"/>
        <Button x:Name="btnCenterScreen" Content="WindowStartupLocation = CenterScreen" HorizontalAlignment="Left" Margin="10,34,0,0" VerticalAlignment="Top" Width="300" Click="btnCenterScreen_Click"/>
        <Button x:Name="btnManual" Content="WindowStartupLocation = Manual" HorizontalAlignment="Left" Margin="10,57,0,0" VerticalAlignment="Top" Width="300" Click="btnManual_Click" />


    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WindowStartupLocation
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnCenterOwner_Click(object sender, RoutedEventArgs e)
        {
            Window2 w2 = new Window2();
            w2.Owner = this;

            double width = this.Width - 50;
            double height = this.Height - 50;

            w2.Width = width > MinWidth ? width : MinWidth;
            w2.Height = height > MinHeight ? height : MinHeight;

            w2.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
            w2.Show();

        }

        private void btnCenterScreen_Click(object sender, RoutedEventArgs e)
        {
            Window2 w2 = new Window2();

            w2.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
            w2.Show();

        }

        private void btnManual_Click(object sender, RoutedEventArgs e)
        {
            Window2 w2 = new Window2();

            w2.Left = this.Left + 50;
            w2.Top = this.Top + 50;

            w2.WindowStartupLocation = System.Windows.WindowStartupLocation.Manual;
            w2.Show();

        }
    }
}

Window x:Class="WindowStartupLocation.Window2"
        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:WindowStartupLocation"
        mc:Ignorable="d"
        Title="Window2" Height="300" Width="300"
        Background="Yellow">
   
    <Grid>
       
    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WindowStartupLocation
{
    /// <summary>
    /// Interaction logic for Window2.xaml
    /// </summary>
    public partial class Window2 : Window
    {
        public Window2()
        {
            InitializeComponent();
        }
    }

Kako radi i kako izgleda ova WPF aplikacija, najbolje da pogledate u video-u:


( WPF - Windows Presentation Foundation - 5#. WindowStartupLocation )

Kako da napravite providan WPF prozor?

Pravljenjem WPF prozora providnim nije baš jednostavan proces kako bi ste to radili sa Windows Forms. U sledećem primeru pogledajte kako se to postiže, ali imajte u vidu da postoji više načina kako možete napraviti Titlebar i kontrolnu dugmad. Npr. možete odvojiti Titlebar i WPF prozor različitim panelima. Ovo je odličan i najjednostavniji način ukoliko ne menjate veličinu prozora. Naravno ovde možete dodati da se boja kontrolni dugmadi menja kada postavite kursor miša iznad njih. Ali to se radi trigerima, što ću vas učiti kasnije u ovom tutorijalu.

<Window x:Class="HowtoMakeATransparentWindow.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:HowtoMakeATransparentWindow"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        AllowsTransparency="True"
        WindowStyle="None"
        Background="Transparent" >

    <Canvas MouseDown="Canvas_MouseDown">
        <Canvas.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="Black" Offset="0"/>
                <GradientStop Color="#3F2738F1" Offset="1"/>
            </LinearGradientBrush>
        </Canvas.Background>

        <Label x:Name="lblClose" Content="X" Canvas.Left="497" Canvas.Top="10" Foreground="Azure" MouseLeftButtonDown="lblClose_MouseLeftButtonDown"/>
        <Label x:Name="lblMinimize" Content="-" Canvas.Left="477" Canvas.Top="10" Foreground="Azure" MouseLeftButtonDown="lblMinimize_MouseLeftButtonDown"/>
        <Label x:Name="lblTitle" Content="The Transparent Window" Canvas.Left="10" Canvas.Top="5" Foreground="White" FontSize="14"/>




    </Canvas>

</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace HowtoMakeATransparentWindow
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
        {
            // You must check is there the left mouse butten clicked or
            // you will get an error

            if (Mouse.LeftButton == MouseButtonState.Pressed) DragMove();

        }

        private void lblClose_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Close();

        }

        private void lblMinimize_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.WindowState = WindowState.Minimized;

        }
    }
}

Kako radi i kako izgleda ova WPF aplikacija, najbolje da pogledate u video-u:


( WPF - Windows Presentation Foundation - 6#. How to Make A Transparent Window )