Alex Khang - Professional WPF and C# Programming - Practical Software Development Using WPF and C#-Independently Published (2019)
Alex Khang - Professional WPF and C# Programming - Practical Software Development Using WPF and C#-Independently Published (2019)
Alex Khang has hold the technology director position and led
many software projects using .NET Technology, Java,
Android, SQL Server, Oracle, DB2, SAP Anywhere, Data
Warehouse, Big Data, Data Science, AI Researcher, Data
Migration, SharePoint Server, Workflow, and Azure Cloud
for companies of German, Singapore, UK, America and
Sweden in past years.
Alex Khang is also teaching the coursework of Software Engineering at Universities.
He is the author of forty-eight (48) best-seller IT books since 2001 to 2012 and four
specialized technology IT books in the University.
Now, you can find many books of mine on Amazon.com
https://www.amazon.com/dp/1097122654/
https://www.amazon.com/dp/B07RDGCH4J
https://www.amazon.com/gp/B084MBSLHM
https://www.amazon.com/dp/B084P4HTFJ
In addition to teaching, Alex.Khang has advised on the Software Engineering and
Solutions for many foreign companies, state companies and e-government projects.
Alex Khang is currently a Data Scientist, AI/ML Engineer, Database Expert, Editor
and Reviewer, and Senior Software Solution Architect and also holds the role of
"Senior Training Manager" at Global Software Development Company.
In additional, he is esteemed member and consultant of
1. SEFIX EcoSystem, a Non-Profit Competency Model Organization
2. edXOps Foundation, a Non-Profit EduTech Foundation
3. StartedAI Organization, an AI Research & Applied Organization.
4. edXBooks 4.0 Express Foundation, a EduTech Foundation
Acknowledgements
Build practical examples for writing this book has been an incredible effort and marked
the return of my writing work.
First of all, I would like to thank my daughter and son for encouraging me to write
this book. They are students learning in the faculty of Computer Science at University,
so they always putting up me the question is “Why you are famous author in past and
working in Software Industry but you are not continuing to contribute your knowledge
and experiences to young people”.
Second, I would like to thank readers and students whom are used to read my
published books multiple times in past and give useful feedback.
Third, I would like to say thanks to my colleagues, for motivating me on going back
to write IT books and supporting me to join online market.
Finally, it is fantastic to serving practical books to all of you, and hopefully I can inspire
to you in next books.
You can enhance .NET-based programming and design skills, you also will
get many esteemed features which can quick help you to develop and
deploy Windows desktop applications for any business solution.
As you read this book and do practice according to the instruction of the
enclosed examples, you always have been holding the following sentence
in your mind: "Now, I am professional WPF developer and I will proud
about myself."
If you interest in the further details of each chapter, please take a look table of
contents on the top page.
Introduction
Welcome to C# and Windows Presentation Foundation (WPF)!
WPF is a key component of the .NET Framework 3.0 and continues to improve
new features in .NET Framework 4.8 and .NET Core 3.0.
WPF is a solid introduction of new technologies, which includes a new graphics
engine that supports 3-D graphics, animation, an XML-based markup language,
called XAML (Extensible Application Markup Language), for declaring the
structure of your Windows UI; and a radical new model for controls, and more;
WPF is another UI framework along with Windows Forms for building Windows
desktop applications that is supported on .NET Core.
WPF and Windows Forms applications only run on Windows. Therefore, they are
part of the Microsoft.NET.Sdk.WindowsDesktop SDK.
You are recommended to use Visual Studio 2019 or newer to use WPF and
Windows Forms with .NET Core, due to WPF represents the best of the control-
based Windows world and the content-based web world.
If you are working in Software Development field and want to build applications
that take full advantages of Microsoft Windows's new user interface capabilities,
you need to learn WPF. Because this new edition is fully updated for running on
.NET Framework 4.8 and .NET Core 3.0.
With this book, the highlight of .NET Core 3 is support for Windows desktop
applications, specifically C# 8, WPF, and UWP XAML. You will be able to run
new and existing Windows desktop applications on .NET Framework and .NET
Core then enjoy all the benefits that .NET Core has to offer.
Software Requirements
To use examples and projects in this books, you need to install Visual Studio 2017
or Visual Studio 2019 or later
Install any edition of Visual Studio 2017 or Visual Studio 2019 from
visualstudio.com with any .NET-related workload.
Visual Studio 2019 automatically includes NuGet capabilities when a .NET
workload is installed.
For more information about installing the latest version of Visual Studio, you can
download at https://visualstudio.microsoft.com/vs/.
https://www.edxbooks.com/download/wpf/
https://github.com/AlexKhangPhd/WPF
https://1drv.ms/f/s!AsNXVbkmDga-bTIeIhsUACsdoEk
https://drive.google.com/drive/folders/17Ga0jDLdqDe9QLxUdLqN4
mkOD8WDEV6s
How to use GitHub Desktop app?
Open Visual Studio 2017 or Visual Studio 2019 -> Select File menu ->
Open and then Project/Solution, gets you to the Open Project dialog box.
The Open Project dialog shows a list of project files you’ve chosen, and it
includes *.sln or *.csproj.
For more information about the code, please open each project and carefully read
the inline description in the code snippet and follow the instructions.
Chapter 1: Background
If customer don’t care Web app or Desktop app but team is solid
experienced with Windows desktop technologies.
Data binding, which allows you to get more clean separation of data and
layout.
Note: The links below are provided for further information of .NET Core 3.0:
https://dotnet.microsoft.com/download/dotnet-core/3.0
Regarding to desktop apps on Windows OS with friendly UI/UX, you can choose
one of Windows Forms or WPF platform as picture below.
If you have never worked with Windows Forms before, and especially for the first
reaching out the WPF, I really encourage you may skip Windows Forms and trust
WPF's robustness in developing the desktop apps as picture below.
However, if you're interested in the differences then read on the following miracle
features that not available in Windows Forms app.
Easy to create an own look and feel as well as powerful styling and skinning
structure
It allows you to make user interfaces for Multimedia, Document, and XPS.
XAML makes it easy to create and edit your GUI, and allows the work to
be split between a designer and a developer.
It allows user to trigger the events, drag and drop file or folders into GUI
area.
5. WPF Windows
The following figure illustrates the constituent parts of a window.
Basic of WPF window is divided into two areas: the non-client area and client area.
The non-client area of a window is implemented by WPF and includes the parts
of a window that are common to most windows, including the following elements:
A border.
A title bar.
An icon.
A Close button.
A System menu with menu items that allow users to minimize, maximize,
restore, move, resize, and close a window.
The client area of a window is the area within a window's non-client area and is
used by developers to add application-specific content, such as menu bars, tool
bars, and controls. In WPF, a window is encapsulated by the Window class that
you use to do the following elements:
Display a window.
Note: The Window is the root of a WPF app, the Page is the root of a UWP app,
WPF window is similar the form concept in Windows Forms App.
6. XAML Overview
XAML is a declarative XML-based language developed by Microsoft that is used
for initializing structured values and objects.
XAML is a declarative markup language. As applied to the .NET Framework
programming model, XAML simplifies creating a UI for a .NET Framework
application.
Note: The links below are provided for further information of XAML definition:
https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/xaml-in-
wpf
You can create visible UI elements in the declarative XAML markup, and then
separate the UI definition from the run-time logic by using code-behind files,
joined to the markup through partial class definitions.
When represented as text, XAML files are XML files that generally have
the .xaml extension. The files can be encoded by any XML encoding, but
encoding as UTF-8 is typical.
Here is an example of XAML in XamlWpfAppSoln project you can download and
use.
Code-behind is a term used to describe the code that is joined with markup-defined
objects, when a XAML page is markup-compiled. This topic describes
requirements for code-behind as well as an alternative inline code mechanism for
code in XAML.
Here is design viewer shows XAML code.
Here is .g.cs and .g.i.cs files of C# code-behind for creating the UI you can find it
in obj\debug folder.
7. Explore UWP
Today, Microsoft's Universal Windows Platform (UWP) is about much more than
truly modern universal applications. It's a platform that allows developers to take
advantage of all the new Windows 10 features introduced over the last couple of
years, regardless of whether your app is universal, a legacy Win32 program, or even
a progressive Web app.
WPF
ASP.NET EF
Windows ML.NET
Core Core
Forms
EF6
cross-plat
.NET STANDARD
UWP in its current form welcomes many app types, and while that's great news
for now, it is a bit of a compromise when it comes to Microsoft's future ambitions
for Windows platform.
Actually, just like Win32 programs, developers are welcome to build native UWP
apps in a number of ways, using languages such as C#, JavaScript, XAML, HTML,
React Native, and more.
Note: The links below are provided for further information of UWP XAML
definition: https://docs.microsoft.com/en-us/windows/uwp/xaml-
platform/xaml-overview
Note: the links below are provided for further information of Visual Studio:
https://visualstudio.microsoft.com/vs/
The New Project dialog opens, under the Installed category, expand either
the Visual C# node, then select Windows Classic Desktop
For Universal Windows Platform (UWP) on Windows 10. You can select
the list of templates on the left, choose Installed > Visual C# > Windows
Universal to see the list of UWP project templates.
Next, the target version/minimum version dialog appears. The default settings are
fine for this tutorial, so select OK to create the project.
When your new project opens, its files are displayed in the Solution
Explorer pane on the right. You may need to choose the Solution Explorer tab
instead of the Properties tab to see your files
Select the WPF App (.NET Framework) template, and enter the name
HelloWorld
Select Browse button and select path to store project files then OK.
Click on OK button, when your new project opens, its files are displayed in
the Solution Explorer pane on the right. The first window appears as following
picture.
In case of select the UWP app, the new UWP project opens look like.
Note: Although the Blank App (Universal Window) is a minimal template, it still
contains a lot of files. These files are essential to all UWP apps using C#. Every
project that you create in Visual Studio contains them.
Drag the Label control from Toolbox and drop the center of
MainWindow, then enter the content is Hello WPF World.
In case of UWP app, select the TextBlock control from Toolbox and drag and
drop the center of MainPage, then enter the content is Hello UWP World.
2. Project Windows
2.1. Solution Explorer
After creating the project successfully, at least a default window appears as follows.
The Solution explorer is a special window in available in the Visual Studio IDE
that enables you to manage solutions, projects, and files. In case of many projects,
to make default start up project, you can right click on Solution Explorer and select
a Project name then select “Set as StartUp Project” as follows.
It provides a complete view of the files in a project, and it enables you to add or
remove files and to organize files into subfolders.
UWF App
WPF App
The Toolbox window displays controls that you can add to Visual Studio projects.
To open Toolbox, choose Toolbox on the View menu. ... Toolbox displays only
those controls that can be used in the current designer. You can search within
Toolbox to further filter the items that appear.
WPF App
UWF App
The Properties window is used to display properties for objects selected in the
two main types of windows available in the Visual Studio IDE.
WPF App
UWF App
3.1. MainWindow.xaml
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://s
chemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HelloWold"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label x:Name="label" Content="Hello WPF World"
HorizontalAlignment="Left" Margin="190,169,0,0"
VerticalAlignment="Top"/>
</Grid>
</Window>
MainWindow.xaml.cs – C# Code
using System;
using System.Windows;
namespace HelloWold
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow: Window
{
public MainWindow ()
{
InitializeComponent ();
}
}
}
3.2. App.xaml
App.xaml file is the declarative starting point of your application, it works much
like for a Window, where the two files are partial classes, working together to allow
you to work in both XAML and Code-behind.
</Application.Resources>
</Application>
App.xaml.cs extends the Application class, which is a central class in a WPF app
as C# code below.
App.Xaml.cs – C# Code
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace HelloWold
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App: Application
{
}
}
WPF extends the core support in the Microsoft .NET Framework for embedded
resources with support for three kinds of non-executable data files: resource,
content, and data.
You can see non-executable data files in next projects such as Image and SQL
Server Service-Based Database or SQL Server Expression LocalDB.
Default UWP project components are different logic with WPF project, as shown
here.
4.2. App.xaml
Notice a few things in UWP App.xaml.cs look more interesting and different than
App.xaml.cs in WPF.
4.3. MainPage.xaml
After created UWP project successful, the MainPage XAML code should look like.
Default code-behind MainPage.xaml.cs file that contains code to handle the events
declared in MainPage.xaml. This file contains a partial class for the window defined
in XAML.
MainPage.xaml.cs – C# Code
using Windows.UI.Xaml.Controls;
namespace HelloWorldUWP
{
public sealed partial class MainPage : Page
{
public MainPage ()
{
this.InitializeComponent ();
}
}
Once add new Window or class into project, namespace is default namespace as
picture below.
To build and run the WPF App, you can press F5 button or ►Start icon or select
Debug | Start Debugging, once a program is started, HelloWorld app looks like
picture.
To remove the "Go to Live Visual Tree" / "Enable Selection" / "Display layout
adorners" / "track focused elements" overlay when debugging. You can simply
select Debug -> Options -> Debugging -> General -> Enable UI Debugging
Tools for XAML -> and uncheck “Show runtime tools in application”.
To build and run the UWP App, you can press F5 button or ►Start icon or select
Debug | Start Debugging, the error window can be look like picture.
Make sure ensure the target device has developer mode enabled by check on
Developer mode option.
Once a program is started, HelloWorldUWP app looks like picture UWP App
Next, change “HelloWold\” into MultiWindows\” and save then close this file.
Open WPF project by selecting the MultiWindowsSoln.sln, now you can see the
solution name is MultiWindowsSoln and project is still name HelloWorld
To change project name from HellowWorld to MultiWindows, you can right click
on project name -> Rename, enter the new name is MultiWindows.
To change the namespace name for cloned project, you can right click on project
name -> enter new name.
Next step, you can rename namespace in C# code by right clicking on HelloWorld
-> select Rename.
Now, you can see new namespace name updated to MultiWindows in App.xaml
file as picture below.
To change the assembly name for cloned project, you can right click on project
name -> enter new name is MultiWindows as picture below.
Now, you can see new assembly name MultiWindows.exe in Debug folder as
picture below.
To clear old assembly files, you can delete these files by using Delete command
from Windows Explorer or in Solution Explorer -> Right clicking on project name
-> Clean.
8. Implementing a Window
Dependent on the purpose of business, the WPF App has one or many windows,
to add window to project you can select Project | Add Window
There are many types of WPF Window, to add normal window you can select
Window and enter name as picture below.
You can add any WPF controls to AboutUs window. Here is example of Label
control.
To open AboutUs window from MainWindow window, you add the Button
control to MainWindow XAML design view.
To open a window when the user clicks on Button control, you create an instance
of the Window class and call in the Click even when the current window is active
window.
Firstly, in XAML design view, double-click the control for which you want to
create a server-side event. For instance, double-clicking a Button control in design
view, it will create an event handler for the Click and then you can use Show
method to open AboutUs window.
Secondly, back to design view and edit XAML code, you can see the attribute
Click="button_Click".
<Grid>
<Label x:Name="label" Content="Hello WPF World"
HorizontalAlignment="Left" Margin="202,93,0,0"
VerticalAlignment="Top"/>
<Button x:Name="button" Content="Button"
HorizontalAlignment="Left" Margin="215,267,0,0"
VerticalAlignment="Top" Width="75"
Click="button_Click" />
</Grid>
Finally, press F5 or click on ►Start icon, it will run the WPF App and
MainWindow layout looks like.
Click on Button, you would get AboutUs window that looks like the picture below.
To open AboutUs window on the center of screen, you can set CenterScreen for
WindowStartupLocation property
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:MultiWindows"
mc:Ignorable="d"
Title="AboutUs" Height="300" Width="300"
WindowStartupLocation="CenterScreen">
Now, press F5 or click on ►Start icon, it will run the WPF App and MainWindow
and AboutUs layout looks like.
Generally, for AboutUs window using Show method is useful when you want to
focus both on a child as well as a parent window where you can perform any action
on parent window.
Show dialog is useful when you don’t want to focus on parent window after child
window is opened and you can’t perform any action on parent window, like disable
the parent window.
Firstly, you need to add new window and name is SignIn and set CenterOwner for
WindowStartupLocation property.
Note: Add two label controls on the SignIn window and enter content User
name and Password as above picture.
By using the ShowDialog method, I will show you a demo on how the show
dialogue differs from show to open a popup window via the load event of the
parent window.
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006
xmlns:local="clr-namespace:MultiWindows"
mc:Ignorable="d"
Title="SignIn" Height="133.663" Width="300"
WindowStartupLocation="CenterOwner"
WindowStyle="None">
<Grid>
<Label
x:Name="label" Content="User name" HorizontalAlignment="Left"
Margin="34,30,0,0" VerticalAlignment="Top"
RenderTransformOrigin="0.447,0.115"/>
<Label
x:Name="label1" Content="Password" HorizontalAlignment="Left"
Margin="34,61,0,0" VerticalAlignment="Top"
RenderTransformOrigin="0.5,1.231"/>
<Label
x:Name="label2" Content="Please enter your user name and
password." HorizontalAlignment="Left" Margin="34,4,0,0"
VerticalAlignment="Top" RenderTransformOrigin="0.342,0.462"/>
<TextBox
x:Name="textBox" HorizontalAlignment="Left" Height="23"
Margin="116,35,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="212"/>
<PasswordBox
x:Name="passwordBox" HorizontalAlignment="Left" Height="23"
Margin="116,64,0,0" VerticalAlignment="Top" Width="212"/>
</Grid>
</Window>
Edit MainWindow under design view, select icon on Properties window and
double-clicking Loaded event.
It will create an event handler for the Loaded and then you can use ShowDialog
method to open SignIn window in Window_Loaded () method, and here is
example of using ShowDialog method.
Again, press F5 or click on ►Start icon, it will run the WPF App and MainWindow
and SignIn layout looks like
Now you can’t perform action on parent window until closing dialog window or
you cannot switch to other windows unless the current window is closed, this type
of window is also known as a modal window, and restricts user input.
If you click the icon on the right top window, it close automatically. But you
can close open window by using Close () method as example.
this.Close();
}
Under XAML design view, Add Button control to SignIn window and and name
is buttonClose. Here is XAML code of buttonClose button.
By default, a WPF application exits completely when all of its windows are closed.
This is not suitable for a background application that minimizes to the system tray,
or for programs that cannot operate when their main window is closed.
Always send the confirmation box with Yes/ No or OK/Cancel to the user and
exit the application if accepted.
In main window, if you click the top right button or any of the methods call
for main application window closer, Window_Closing() grabs the event for shut
down if user confirms.
There is the second way to return an exit code from your WPF app by explicitly
calling Application.Current.Shutdown () method, you can pass an exit code value
during that call.
Note: To return an exit code from your WPF app, you can use this.Close ()
method in window except main application window
buttonCancel_Click - Application.Current.Shutdown
private void buttonCancel_Click (object sender, RoutedEventArgs e)
{
if (MessageBox.Show("Are you sure to exit?", "XOKR",
MessageBoxButton.YesNo, MessageBoxImage.Question,
MessageBoxResult.Yes) == MessageBoxResult.Yesy)
{
//do something before exit
Application.Current.Shutdown ();
}
else
{
//do something before close
this.Close ();
}
}
Now, confirmation box will display when you click on Cancel button from SignIn
window.
If you want to force a WPF application to exit click Yes button, otherwise click
No button closing this window.
9. Splash Screen
9.1. WPF Splash screen
Splash screens are typically used by particularly large applications to notify the user
that the program is in the process of loading. A splash screen disappears when the
application's main window appears.
Other hands, the splash screen is generally just a display screen to orient users and
give them something to look at while hardware is working to present the software
to them.
The Microsoft logo on Microsoft Visual Studio is an excellent example of a splash
screen. The following picture is present the splash screen of Visual Studio 2019.
In fact, splash screens give UI designers or developers the chance to make a bold
first impression and reinforce brand identity.
Note: You can create new window and add two label controls on the
SplashScreen window and enter content XOKR Player and Version 5.0, Image as
above picture.
To implement available splash screen class of your WPF desktop app, you need to
add new SplashScreen image and name is XOKRSplashScreen.pnp.
The SplashScreen class can display any image format that is supported by the
Windows Imaging Component (WIC).
For example, you can use the BMP, GIF, JPEG, PNG, or TIFF format. If the
image is a PNG file and it includes an alpha channel, the image is rendered using
the transparency defined in the alpha channel.
Now, you edit XOKRSplashScreen.pnp and draw new image or copy / paste
image from any graphic software into XOKRSplashScreen.pnp as picture below.
Note: You can create new window and add two label controls on the
SplashScreen window and enter content XOKR Player and Version 5.0, Image as
above picture.
By using the Show method with autoClose and topMost parameters, I will show
you a demo on how the show SplashScreen window via the constructor or event
of the parent window.
The following code example shows how to create and display a startup window by
calling the SplashScreen object after InitializeComponent () method.
Again, press F5 or click on ►Start icon, it will run the WPF App and SplashScreen
displaying looks like.
Note: A TimeSpan that specifies how long it will take for the splash screen to
fade after the close operation has been initiated.
The splash screen is displayed by using native code, before the WPF application
instance is created.
The splash screen is displayed in the center of the screen, when the application is
loaded, the splash screen fades and disappear basing on the TimeSpan.
In this example, when the application is loaded, the splash screen fades and
disappear after then The SignIn window is displayed in the center of the screen.
Note: The splash screen will automatically be created, displayed, and destroyed in
another thread. You don't need to worry about creating or closing the splash
screen, as that is done automatically.
Built-in Splash Screen is not meet your expectation, you can design and handle
behavior of appearances on screen by create new window.
Assumpt that you want a splash screen that would display until the main window
is ready to display.
Firstly, add new window and name is SplashWelcome as follows.
Secondly, set values properties for window such as a borderless, immovable form
with your text on it, set to initially display at the center of the screen as follows.
Here is example illustrates how to use XAML to set the Window properties and
Label properties.
Finally, look at the App.xaml.cs file, the OnStartup method below will complite
and work properly if you rewrite override it to look like this.
Once you've done above steps, you can run your app and see the window appear
splash on in shortly and disappear after then and the main window should be as
shown as the following figure.
1. WPF Controls
WPF allows developers to easily build and create visually enriched UI based
applications. The classical UI elements or controls in other UI frameworks are also
enhanced in WPF applications.
WPF ships with many of the common UI components that are used in almost
every Windows desktop apps, such as Button, Label, TextBox, Menu, and ListBox.
Note: The rest of controls can be created similarly; the links below are provided
for further information of WPF controls: https://docs.microsoft.com/en-
us/dotnet/framework/wpf/controls/
Many controls have properties that allow you to change how the control appears,
such as the Background of a Button.
You can set the value properties in both XAML and code. The following example
sets the Name property on a Grid control in XAML.
<Window
x:Class="WpfApplication1.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" Loaded="Window_Loaded">
<Grid Name="MainLayout">
</Grid>
</Window>
You can add a control to an application by using either XAML or code. The
following example shows how to add a TextBlock control into Grid control by
using C# code.
Once you use C# code to add control other controls, the effect on WPF window
is that no one can write anything to that Textbox, the only keys that work are space
and backspace and you cannot paste something to that TextBox.
Note: When a WPF window is opened modeless, you have to call the
EnableModelessKeyboardInterop method from ElementHost to forward all
keyboard messages.
The following example shows how to create a simple application that asks a user
for their full name, gender, marital status, certificate, department name, city name
and join date by using Label, TextBox, Image, CheckBox, RadioButton,
ComboBox, DatePicker and Button, in XAML.
<TextBox
Height="26" HorizontalAlignment="Left"
Margin="117,52,0,0" Name="Email"
VerticalAlignment="Top" Width="187"
Text="Initial text contents of the TextBox.">
</TextBox>
The following graphic shows an example of a TextBox with “Initial text contents
of the TextBox”.
To customize the TextBox Control, you can apply the same property settings to
multiple TextBox controls, use the Style property. You can modify the default
ControlTemplate to give the control a unique appearance.
The following example shows how to fill color for Background of TextBox by
XAML code.
</TextBox>
The following graphic shows an example of a TextBox with “Initial text contents
of the TextBox” and Background is Black color.
1.1.3. RichTextBox
RichTextBox control is Input control, it represents a rich editing control which
operates on FlowDocument objects.
Content="M.B.A" Height="16"
HorizontalAlignment="Left" Margin="110,161,0,0"
Name="checkBox1" VerticalAlignment="Top" Tag="0"
IsChecked="True"/>
<CheckBox
Content="B.A" Height="16" HorizontalAlignment="Left"
Margin="169,161,0,0" Name="checkBox2"
VerticalAlignment="Top" Tag="1" />
The following graphic shows an example of two CheckBoxes with contents are
"M.B.A" and "B.A".
In case of inserting image for check box controls, you can Image control and
TextBlock controls as following example.
</StackPanel>
</CheckBox.Content>
</CheckBox>
The following graphic shows an example of CheckBox control with contents are
"M.B.S" along with image of hot.gif.
Note: You can group RadioButton controls by placing them inside a parent or by
setting the GroupName property on each RadioButton.
The IsChecked property of a RadioButton can be set by clicking it, but it can only
be cleared programmatically.
The following graphic shows an example of four RadioButtons with contents are
"Male" and "Female" for Gender group and "Single" and "Married" for
MaritalStatus group.
Note: Declaration of XAML code or C# code are using for ComboBox control,
you can apply for ListBox control.
The Background property specify how to gets or sets a brush that describes the
background of a ComboBoxItem. The IsSelected property of a ComboBox can
be gets or sets a value that indicates whether an item is selected under XAML
Code.
The graphic displays the default selected item of the ComboBox control.
The example also creates a TextBlock, Image and CheckBox controls that displays
the selected item of the ComboBox.
The graphic displays the ComboBoxItem with CheckBox, Image and Content of
the ComboBox.
You can use C# code to add ComboBoxItem control into ComboBox. The
following example add two ComboBoxItem to a ComboBox.
//Initializes the second Item object and set values to Id, Name properties
item = new Item();
item.Id = "A002";
Note: Moreover, you can see the example populates the ComboBox by binding
the ItemsSource property to a collection object of type ObservableCollection or
IEnumerable in Chapter 5.
Image control is Media control; it represents a control that displays an image. The
example also creates an Image control that displays the image from absolute path.
<Image
Height="119" HorizontalAlignment="Left"
Margin="352,34,0,0" Name="image1" Stretch="Fill"
VerticalAlignment="Top" Width="120"
Source="/WpfApp1;component/Images/hot.gif"
/>
Given example below is the most commonly used properties of Image. You can
use an example also adds an image file from absolute path to Image control that
can displays on WPF window.
Here is demonstration to show how to use C# code to display the image on Image
control.
Here is an example how you can get image under binary data types and display on
Image control.
Date controls are used to display and select calendar information. Dependent on
business transaction scenario on UI, you can use DatePicker or Calendar control
for your proper intention.
Remarks, the DatePicker control allows the user to select a date by either typing it
into a text field or by using a drop-down Calendar control.
Here is demonstration of above example. You can see the list of files in D: drive
which are created on same year with selected year.
Note: To display the text as tip text on specific control, you can use its Tooltip
property.
<Grid>
<ProgressBar x:Name="progressBarScan1"
HorizontalAlignment="Left" Height="20"
Margin="21,35,0,0" VerticalAlignment="Top"
Width="547"/>
<Button x:Name="buttonScan" Content="Scan"
HorizontalAlignment="Left" Margin="21,74,0,0"
VerticalAlignment="Top" Width="75"/>
<TextBlock x:Name="textBlock1"
HorizontalAlignment="Left" Margin="21,10,0,0"
TextWrapping="Wrap" Text="" VerticalAlignment="Top"
Width="547"/>
<ProgressBar x:Name="progressBarScan2"
HorizontalAlignment="Left" Height="20"
Margin="21,78,0,0" VerticalAlignment="Top"
Width="547"/>
<TextBlock x:Name="textBlock2"
HorizontalAlignment="Left" Margin="21,60,0,0"
TextWrapping="Wrap" Text="" VerticalAlignment="Top"
Width="547"/>
</Grid>
To update the progress of the ProgressBar control and make it to refresh correctly
on the window or form, you need to use the Invoke method of the Dispatcher
class to update the progress of the ProgressBar and cause it to correctly refresh.
Here is example of ScanFolders method with an argument for specifying the folder
name.
DispatcherPriority.Background,
new object [] {ProgressBar.ValueProperty, j});
//Suspend 1 milisecond before go next action
System.Threading.Thread.Sleep (15);
ScanFolders (textBlock1.Text);
}
progressBarScan1.Value = progressBarScan1.Maximum;
}
When program is started, you can click on ProgressBar button and here is demo
how you update value for ProgressBar control and folder name on TextBlock
control as well.
In case of scan all files in current folder name, you need to call ScanFiles method
before ScanFolders as below.
ScanFiles method receives the directory path as its argument and update value for
ProgressBar control as well as file name for TextBlock control.
//CallGetFiles method with specific path and get name of all files
FileInfo [] fileInfos = new
DirectoryInfo (path). GetFiles ();
progressBarScan2.Maximum = fileInfos.Count ();
progressBarScan2.Minimum = 0;
progressBarScan2.Value = 0;
And here is demo how you update the first value for ProgressBar1 control and
folder name on TextBlock1 control and the second value for ProgressBar2 control
and file name on TextBlock2 control.
Directories are often nested, so sometimes we need a list of files in a folder, and
also those in each subdirectory. Here is an example for calling ScanFiles method
in ScanFolders method to display the files in the specified directory.
Content="OK" Width="60"/>
</StatusBarItem>
<Separator/>
<StatusBarItem>
<TextBlock x:Name="title">
Online support: Microsoft.com</TextBlock>
</StatusBarItem>
<StatusBarItem HorizontalAlignment="Right">
<Image Source="Images\help.png"
Width="16" Height="16" />
</StatusBarItem>
</StatusBar>
Run WPF application, click StatusBar button from MainWidnwo you can get
demo of DockPanel control and DockPanel.Dock property as picture below.
In this example, you can use the DockPanel control which will make it easy to
dock content in all four directions (top, bottom, left and right). The
DockPanel.Dock property, which decides in which direction you want the child
control to dock to.
Here is an example of adding two controls (ListBox and Image controls) after
StatusBar control.
Run WPF application again, click StatusBar button from MainWindow and you
can get demo of above example as picture below.
listBoxDirectory.Items.Add (folder);
}
}
The Menu control presents a list of items that specify commands or options for
an application. Typically, clicking an item on a menu opens a submenu or causes
an application to carry out a command.
Click="MenuItem_Click_3" />
<MenuItem Header="DrawImage"
Click="MenuItem_Click_4" />
<MenuItem Header="Moving"
Click="MenuItem_Click_5" />
</MenuItem>
<MenuItem Header="Reports" />
<MenuItem Header="Help" />
</Menu>
As you can see on the screenshot below, the menu currently has some the
submenus through your tasks, which means you can drop and select the submenu
of the corresponding function.
Run application again, you can see on the screenshot below, the menu Help
currently has an icon and the submenu Search has icon too.
<MenuItem.Icon>
<Image Source="/Images/hot.gif" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Cut" Name="menuCut"/>
<MenuItem Header="Send to">
<MenuItem Header="Bluetooth device"/>
<MenuItem Header="Documents" />
</MenuItem>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
Right Clicking
To display the list of directories as above screen, you need to define C# code in
Loaded event of window.
Click ="MenuItem_Documents_Click"/>
</MenuItem>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
The Toolbar is located on the top side of the desktop app; it consists of a number
of menu icons with its handler. The different nodes are grouped under these icons
based on their functions.
You use the ToolBarTray control to represent the container that handles the layout
of a ToolBar and Toolbar control to provide a container for a group of commands
or controls.
By instantiating program and calling the ToolBar button, the next window is
shown with three icons (cut, copy and paste) as below picture.
The following example shows how to create two ToolBar controls inside a
ToolBarTray control. The example uses the BandIndex property to place tool bars
inside tool bar trays.
</Button>
<Button>
<Image Source="Images\excel.png" Width="20"/>
</Button>
<Button>
<Image Source="Images\powerpoint.png"
Width="20"/>
</Button>
</ToolBar>
</ToolBarTray>
Again instantiating program and calling the ToolBar button, the next window is
shown with the first ToolBar control containing three icons and the second
ToolBar control containing three icons as below picture.
1 2
By selecting the second ToolBar control and dragging then dropping right before
the first ToolBar control, and the ordinal of both ToolBar controls as follows.
2 1
The example uses the ToolTip property to add text to each icon.
Run app again, ToolTip text is shown on icon once you move cursor to tool bar
button as follows.
<StackPanel
HorizontalAlignment="Left" Height="100"
VerticalAlignment="Top" Width="600"
Orientation="Horizontal">
<Button x:Name="buttonGridControl"
Content="GridControl Control" Height="26" />
<Button x:Name="buttonScrollViewer"
Content="ScrollViewer Control" Height="26" />
<Button x:Name="buttonListView"
Content="ListView Control" Height="26" />
<Button x:Name="buttonTreeView"
Content="TreeView Control" Height="26" />
</StackPanel>
If you want to insert the space between two buttons, you can use TextBlock
control as XAML code.
Run app again, the following demo shows horizontal orientation of button
controls on window which displayed the name of controls as follows.
By default, rows and columns take up the least amount of space necessary to
accommodate the largest content within any cell contained in a given row or
column.
For instance, there are three rows specifying height <RowDefinition Height="29"
/> and there are three columns specifying width <ColumnDefinition Width="80"
/>.
Note: Columns and rows that are defined within a Grid can take advantage of *
sizing to distribute remaining space proportionally. When * is selected as the
height or width of a row or column, that column or row receives a weighted
proportion of the remaining available space.
Run app again and you can see demo of four columns and four rows of Grid
control which contains TextBlock and TextBox controls.
In case of merging cells in Grid control, you can use the Grid.ColumnSpan or
Grid.RowSpan properties.
Note: Grid is the only layout panel that can distribute space in this manner.
Let's add last row and merge the first three columns into one column so, you will
see the actual differences in the Grid control.
Height="23" HorizontalAlignment="Right"
Margin="12,6,0,0" Name="textBlockSummary"
Text="Grand Total Amount: "
VerticalAlignment="Top" />
Run app again and you can see TextBlock control place on merged three columns.
<TreeView
x:Name="treeViewCountry"
Width="150" Height="Auto" Grid.Column="0"
Grid.RowSpan="2" Grid.Row="2">
<TreeViewItem Header="United States">
<TreeViewItem Header="New York"/>
<TreeViewItem Header="Los Angeles"/>
<TreeViewItem Header="Chicago"/>
</TreeViewItem>
<TreeViewItem Header="French">
<TreeViewItem Header="Paris"/>
<TreeViewItem Header="Marseille"/>
<TreeViewItem Header="Lyon"/>
<TreeViewItem Header="Toulouse"/>
</TreeViewItem>
<TreeViewItem Header="United Kingdom">
<TreeViewItem Header="London"/>
<TreeViewItem Header="Birmingham"/>
<TreeViewItem Header="Cambridge"/>
<TreeViewItem Header="Manchester"/>
</TreeViewItem>
</TreeView>
The following illustration shows a simple TreeView with 3 countries and their
cities.
The following example shows how to specify an event handler for the
SelectedItemChanged event for getting selected city name.
The following demo shows the usage of the SelectedItemChanged event to get city
name from TreeViewItem element.
In some cases, no need to read data from the database while the user selects the
city name via the SelectChanged event. Instead, you should call the method of
reading data every time the user double click.
Here is demo of the Double Click event and you can find C# code of ShowOrders
() method in Chapter 5.
The following example shows how to create a ListView control that implements a
GridView as its View.
The following illustration shows a simple ListView with sale orders of 3 countries
and their cities.
The following example shows how to add an item into ListView control
programmatically by using C# code.
{
//Get selected tree view item
TreeViewItem item = (TreeViewItem)
treeViewCountry.SelectedValue;
if (item != null)
{
string cityName = Convert.ToString (
item.Header);
textBlockTitle.Text = string.Format (
"Orders - {0}", cityName);
//Call ShowOrders method with specific city name
ShowOrders (cityName);
}
else
{
MessageBox.Show("Please select city name and
click Display button again.");
}
}
The following demo shows the usage of the buttonLoad_Click handler to call
ShowOrders method.
As you've seen in the ShowOrders () method, there are many "Order" objects
created, the following example will show the specification of this class.
Note: This overview focuses on the style and template aspects of the application
and does not discuss any data binding concepts.
1. Styles
A Style is basically an object with a bunch of setters that will be executed on the
consuming control to set its properties. It also contains triggers that will invoke a
setter based on some state event.
A Style is just a convenient way to apply a set of property values to more than one
element. For example, consider the following TextBlock elements and their default
appearance.
The code examples used in this overview are based on a little change of styles and
simple text (New Registration) sample shown in the following illustration.
It represents a setter that applies a property value, you can change the default
appearance by setting properties, such as FontSize, Foreground, FontFamily and
HorizontalAlignment on this TextBlock element directly by using Setter.
Note: Note that you must specify both the Property and Value properties on a
Setter for the setter to be meaningful. If one or both properties are not set, an
exception will be thrown.
The following example defines a Style that will be applied to every TextBlock
element as shown here.
The Style defines a Trigger element that changes the properties of a WPF control.
The following example shows the changes the Foreground and Background
properties of a button when the IsMouseOver property is true.
Click="buttonClose_Click" Margin="29,131,266,10">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Foreground"
Value="Red" />
</Trigger>
<Trigger Property="IsPressed"
Value="True">
<Setter Property="Foreground"
Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Run app again, the “Close” button appear background color is Gray and Red color
while user mouse over as follows.
MultiTrigger is used to set action on Multiple Property change. It will execute when
all condition is satisfying within MulitTrigger.Condition.
</Button>
Run app again, the “Exit” button appear background color is Gray and Red color
with bold border while user mouse over as follows.
2. Template
The ControlTemplate contains the tree of elements that define the desired look.
XAML Code
Logic Code
WPF Resources
For WPF Resources, there are three parts of resource you can change
Window.Resource
ControlName.Resource
Application.Resource
The truth is, the arduous of control customization has evidently been felt by the
developers of the WPF app or UWP app available as part of the .NET Framework
and .NET Core as well.
To have an interface reach the limitation of UI / UX concept, They've come up
with an exciting and powerful solution known as the "template".
Every predefined control in the WPF that has a visual appearance also has a
template that entirely defines that appearance. This template is an object of type
ControlTemplate that is set to the Template property defined by the Control class.
When you use a WPF control in your application, you can replace that default
template with one of your own design.
You create a ControlTemplate when you want to customize the control's
appearance beyond what setting the other properties on the control will do.
In some cases, retain the basic functionality of the control-including all the
keyboard and mouse handling-but you can give it a different look.
Controls have many properties, such as Background, Foreground, and
FontFamily, that you can set to specify different aspects of the control's
appearance, but the changes that you can make by setting these properties are
limited.
Note: The links below are provided for further information of ControlTemplate
definition: https://docs.microsoft.com/en-us/visualstudio/designers/creating-a-
ui-by-using-xaml-designer-in-visual-studio?view=vs-2019
The wire up between the logic layer and the template layer is done by concept of
Data Binding, especially when you interact with database.
Here is demo of linking between Template and Logic layers.
Note: Without the ability to create a new ControlTemplate for controls, all
controls in every WPF app would have the same general appearance, which
would limit the ability to create an application with a custom look and feel.
WPF gives you the ability to create a control which appearances can be customized
by using one of three software design.
Fluent Design.
The following example does not change the button's appearance when you move
the mouse pointer over button or click it. Here is demonstration of WPF controls
without style and template.
To create custom control template for first you have shown XAML for Button
control as flowing example.
The ControlTemplate UIElement enables you to change look and feel on controls.
Here's what it looks like.
Orange color that fill the surface of the button. The appearance of the Orange
color indicates whether a "Save" string is not applied to this property. So, you need
to add TextBlock control as follows.
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
HorizontalAlignment="Center"
Click="buttonDelete_Click">
<Button.Template>
<ControlTemplate>
<Grid Width="80"
HorizontalAlignment="Center" >
<Rectangle RadiusX="10"
Fill="Orange" Stroke="Black"
RadiusY="10"/>
<ContentControl
Content="Delete" FontSize="12"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
VerticalAlignment="Center" Width="50"
Foreground="Azure">
</ContentControl>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
Note: The links below are provided for further information of ContentPresenter
definition: https://docs.microsoft.com/en-
us/dotnet/api/system.windows.controls.contentpresenter?view=netframework-
4.7.2
Click="buttonClose_Click">
<Button.Template>
<ControlTemplate>
<Grid Width="80"
HorizontalAlignment="Center" >
<Ellipse Fill="Red" Stroke="Black"/>
<ContentPresenter Content="Close"
FontSize="12" Width="50"
HorizontalAlignment="Center"
VerticalAlignment="Center" >
</ContentPresenter>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
The following image shows the appearance of the Button when this gets applied
ContentPresenter.
2.6.3. TemplateBinding
The TemplateBinding markup extension binds a property of an element that is in
the ControlTemplate to a public property that is defined by the control.
When you use TemplateBinding, you enable properties on the control to act as
parameters to the template.
The following example that uses the TemplateBinding markup extension to bind
property of elements that is in the ControlTemplate to Content property that are
defined by the button.
The following image shows the appearance of the Button when this gets applied
TemplateBinding for ContentPresenter.
Note: The links below are provided for further definition of Styles and
Templates of WPF Controls: https://docs.microsoft.com/en-
us/dotnet/framework/wpf/controls/control-styles-and-templates
Follow the above example of using the trigger to change the button content and
look when Pressed or MouseOver event, the same thing can be expressed in
control states, in a quite similar way is Control also contains triggers that will
invoke a setter based on some state event.
You will probably see some familiar states of Button as following table.
VisualState and Visual State Manager as new feature and many developers has
question when to use VisualState and Visual State Manager and when to use
Triggers in ControlTemplate.
You also see some familiar states of TextBox as following table.
Notice that the Visual State Manager is available in latest version of WPF up to
now, but it doesn’t mean that Triggers are not going to use. Visual State Manager
and VisualState are using to define States of control and using each state that you
can customize the appearance of control.
Note: The links below are provided for further information of VisualState
definition: https://docs.microsoft.com/en-
us/dotnet/api/system.windows.visualstate?view=netframework-4.7.2
Actually, the difference between a button with its default appearance and the
button in the preceding example is that the default button subtly changes when it
is in different states.
The following example uses the VisualState that changes the appearance of a
Button when the mouse pointer is over it. The Storyboard changes the button's
border color by changing the color of the BorderBrush.
x:Name="comboBoxMaritalStatus"
Grid.Column="3" HorizontalAlignment="Left"
Margin="12,6,0,0" Grid.Row="2"
VerticalAlignment="Top" Width="120" Height="25">
<ComboBox.Template>
<ControlTemplate TargetType="ComboBox">
<Border Name="RootElement">
<ContentControl
x:Name="ContentControl" Margin="6,2,25,2"
Content="{TemplateBinding SelectionBoxItem}"
DataContext="{TemplateBinding DataContext}"
ContentTemplate=
"{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector=
"{TemplateBinding ItemTemplateSelector}">
</ContentControl>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="SelectedState">
<Storyboard>
<ColorAnimation To="Red"
Storyboard.TargetName="BorderBrush"
Storyboard.TargetProperty="Color"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border.Background>
<SolidColorBrush
x:Name="BorderBrush" Color="LightCyan"/>
</Border.Background>
</Border>
<ControlTemplate.Triggers>
The above example produces output that is similar to the following illustrations.
The following example shows the five ComboBoxItem elements those are added
into the ComboBox control.
ComboBoxItem – C# Code
void Window_Loaded (object sender, RoutedEventArgs e)
{
//Add 5 types of marital status to combobox item
comboBoxMaritalStatus.Items.Add ("Single");
comboBoxMaritalStatus.Items.Add ("Married");
2.7.2. VisualStateManager
You do not have to write any code to make this occur because the control's logic
changes state by using the VisualStateManager. When the control enters the state
that is specified by the VisualState.Name property, the Storyboard begins. When
the control exits the state, the Storyboard stops.
3. Themes
WPF themes are defined by using the styling and template mechanism that it
exposes for customizing the visuals of any element.
WPF provides support for packaging user interface (UI) resources as a theme by
using a resource dictionary that is encapsulated as the ResourceDictionary class.
You can define resource dictionaries as individual files that enable you to reuse a
theme across multiple applications.
You can also create swappable themes by defining multiple resource dictionaries
that provide the same types of resources but with different values.
Note: The links below are provided for further information of default themes:
https://github.com/Microsoft/WPF-
Samples/tree/master/Graphics/2DTransforms
You can redefine styles or other resources at the application level is the
recommended approach for skinning an application.
The desktop themes determine which resource dictionary is used. To get the
resource dictionaries for the desktop themes. The following table describes the
resource dictionary file names and their corresponding desktop themes.
Note: The links below are provided for further information of resource types:
https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/xaml-
resources
1. ControlName.Resources
Now, you have XAML code setup correctly, you can add the required Resources
property for Save button control. As description of ControlTemplate in previous
example, there is no support for dragging template across the screen, instead easily
added XAML code under design view.
Here is example of DynamicResource and XButtonTemplate for Save button
control.
Output of above example, take a look at the following illustration that shows part
of the Resources with DynamicResource.
In case of using multi templates in Resources, you can define the second
ControlTemplate as follows.
Template="{DynamicResource XButtonTemplate}"
Width="80" Height="26" Content="Save"
HorizontalContentAlignment="Center"
HorizontalAlignment="Center"
Click="buttonSave_Click">
<Button.Resources>
<ControlTemplate x:Key="YButtonTemplate">
<Grid HorizontalAlignment="Center" Width="80">
<Rectangle RadiusX="10" Fill="Orange"
Stroke="Black" RadiusY="10"/>
<TextBlock Width="40"
Text="{TemplateBinding Button.Content}"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="YButtonTemplate">
<Grid HorizontalAlignment="Center" Width="80">
<Rectangle RadiusX="10" Fill="Blue"
Stroke="Black" RadiusY="10"/>
<TextBlock Width="40"
Text="{TemplateBinding Button.Content}"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Button.Resources>
</Button>
Run again above example, take a look at the following illustration that shows part
of the Resources with DynamicResource.
Template="{DynamicResource XTextBoxTemplate}">
<TextBox.Resources>
<ControlTemplate x:Key="XTextBoxTemplate">
<Grid HorizontalAlignment="Center">
<Rectangle
Fill="Coral" Stroke="Black"
Width="{TemplateBinding TextBox.Width}"
Height="{TemplateBinding TextBox.Height}"
/>
</Grid>
</ControlTemplate>
</TextBox.Resources>
</TextBox>
2. Window.Resources
As above example illustrates how simple it is to use Resources in Button and
TextBox controls, but normally you would of course want define one resource but
apply for the many controls and not just a Button or TextBox control.
Following to the above example, you need clone MainWindow without templates
and styles to design new window with a little bit of changes that it will officially be
able to use at this section as follows.
<ControlTemplate
x:Key="XButtonTemplate" TargetType="Button">
<Grid HorizontalAlignment="Center" Width="80">
<Rectangle RadiusX="10" Fill="Orange"
Stroke="Black" RadiusY="10"/>
<TextBlock Width="40"
Text="{TemplateBinding Button.Content}"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!--You can copy code from example
in previous example -->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate
x:Key="YButtonTemplate" TargetType="Button">
<Grid HorizontalAlignment="Center" Width="80">
<Rectangle RadiusX="10" Fill="Blue"
Stroke="Black" RadiusY="10"/>
<TextBlock Width="40"
Text="{TemplateBinding Button.Content}"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Window.Resources>
Here is example use one or more of the following resources for the Save and
Delete buttons.
In this example, there are two button controls which inherits from same resource.
as shown a follows.
Continue along this way and you will define the ControlTemplate for TextBox
under the XAML code in Window.Resources as shown here.
x:Key="YTextBoxTemplate" TargetType="TextBox">
<Grid HorizontalAlignment="Center">
<Rectangle
Fill="LightBlue" Stroke="Black"
Width="{TemplateBinding TextBox.Width}"
Height="{TemplateBinding TextBox.Height}"/>
<ContentControl
Foreground ="{TemplateBinding Foreground}"
Content="{TemplateBinding TextBox.Text}"
VerticalContentAlignment="Center"/>
</Grid>
</ControlTemplate>
Similar example of using resources for Button control, here is example use one or
more of the following resources for the TextBox controls.
Run app again, textBoxIncome and textBoxCode controls which inherits from
same resource. as shown a follows.
3. Application.Resources
Resources are not only applied in Window, but also requested by the order found
within the Application if you declare the Resource in App.xaml and reference them
from within WPF app.
In order to make sure any resource that you reference is defined earlier within the
resources collection than where that resource is then requested.
Note: It is valid if you specify using the template for a Control from
ControlTemplate in Control.Resources or Window.Resources or
Application.Resources.
ComboBox are slightly different in some specialty properties than other controls,
they simply serve as a way to describe an interface to which a control must
conform.
The following example shows a XAML code that references the application-level
resource that the previous example defined. The resource is referenced by using a
DynamicResource that specifies the unique resource key for the requested
resource.
Here is an example use one or more of the following resources for the ComboBox
controls.
Once you defined those out, it only made sense to use that resource which will
change look and feel to the ComboBox control as follows.
Then, you can declare a custom resource dictionary by copying resources from
above examples and paste to ResourceDictionary look like.
Moreover, if you have multiple resources that you are using in Window.Resources
or Application.Resources, you can instead move these resources to resource
dictionary.
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ResourceDictionaryWpfApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary
Source="XResourceDictionary.xaml"/>
</Application.Resources>
</Application>
1. Service-based Database
To apply Data Binding for WPF controls, you can use Visual Studio to create and
update a local database file in Service-Based Database or SQL Server Express
LocalDB.
Note: The links below are provided for further information of SQL Server
Express LocalDB definition: https://docs.microsoft.com/en-
us/visualstudio/data-tools/create-a-sql-database-by-using-a-designer?view=vs-
2019
Create a local database file, on the menu bar, select Project > Add New Item. In
the list of item templates, scroll down and select Service-based Database, name the
database ERP, and then click Add as follows.
If you follow all of the above steps, you will get the following output.
Tables are information containers. Every database needs at least one table without
it, you can’t store any data.
In Server Explorer, expand the Data Connections node, and then expand the
ERP.mdf node as follows.
Open the shortcut menu for Tables, and then select Add New Table. The Table
Designer opens and shows a grid with one default row, which represents a single
column in the table that you're creating.
By adding rows to the grid, you'll add columns in the table. Here is screenshot of
States table.
In the upper-left corner of Table Designer, select Update. You will see the
following output.
Now, the Preview Database Updates dialog box above, you continue to select
Update Database. States table is created to the local database file as follows.
In case of necessary save CREATE TABLE script to sql file, you can click Save
button on tool bar.
To insert data into States table, you can use INSERT statement or COPY and
PASTE the data directly to table by selecting Show Table Data as follows.
Assumption that, you can copy data from Excel and paste to States table, then you
will get the following output.
To connect to ERP.mdf, you can use “data source” property in connection string
as below example.
Note: the links below are provided for further information of SQL Server
editions: https://docs.microsoft.com/en-us/sql/sql-server/editions-and-
components-of-sql-server-2017?view=sql-server-2017
In this book, I decided to use Microsoft® SQL Server® 2017 Express edition,
because it is a powerful and reliable free data management system that delivers a
rich and reliable data store for lightweight Web Sites and desktop applications.
To install SQL Server, you need to download it from the Microsoft.com website
via the following link https://www.microsoft.com/en-us/sql-server/sql-server-
downloads
Now is a good time to check out some of the major changes in SQL Server 2019.
You can download it from the Microsoft.com website via the following link
https://www.microsoft.com/en-us/sql-server/sql-server-2019
After you intalled a newer verison of SQL Server and Microsoft SQL Server
Management Studio (SSMS), you can find any SSMS icon to start up the SQL
Server as follows.
If the Microsoft SQL Server Management Studio menu is clicked, a dialog will be
displayed as below.
As you already know ERP database in the section of Service-based Database, and
now you can consider to reuse this database in SQL Server.
Right clicking on the Databases tab and select New Database, and here is
screenshot shows how to configure a new database.
Just enter name is ERP and keep default value for remaining options. Click OK
button, ERP database would be created as shown here.
To create the new table, you select ERP database -> then right clicking on Tables
tab and continues selecting New Table menu, Table designer view will be opened.
Type a new name is States and click button, and then add more fields to the
table such as the StateCode and StateName as shown in below figure.
If you want to create another table in your database, right clicking on Tables tab -
> selecting on New Table context menu, will be displayed.
In this case, type a new name is Employees and click button, then add more
fields to the table such as the EmployeeId, FirstName, LastName, StateCode,
Address, Email, IsActivated as shown here.
Repeat this process until you’ve have all the neccessary table names. Now, list of
tables looks like this.
In order to insert data into Employees table, you can use INSERT statement or
COPY and PASTE the data directly to table.
For instance, right clicking on Employees table and selecting Edit Top 200 Rows
as follows.
You can copy and pass data collection into this table, once you make the above
steps, you will see the following output.
Note: WPF and Windows Forms can now be used with .NET Core. Microsoft
ship in a new component called “Windows Desktop” that is part of the Windows
version of the SDK.
The data binding functionality has several advantages over traditional models,
including a broad range of properties that inherently support data binding, flexible
UI representation of data, and clean separation of business logic from UI.
OneTime: The property is initially set, but updates to the source are not
copied to the destination.
DependencyObject Object
Binding Object
Dependency OneWay
TwoWay Property
Property
OneWayToSource
Note: The links below are provided for further information of binding mode
definition: https://docs.microsoft.com/en-
us/dotnet/framework/wpf/data/data-binding-overview
DependencyObject Object
Binding Object
Dependency OneWay
TwoWay Property
Property
OneWayToSource
UpdateSourceTrigger
Display OneWay
Member FieldName
DisplayMemberBinding
DisplayMemberBinding
Binding Property
default property
Property
In C#, you can use the keyword class to define a class. There are two sections in
the class declaration: class name with access modifier is public and constructor is
initiate method as follows.
public Education (
string qualification,
string major,
string university,
string country,
string yearAttended,
string grade
)
{
Qualification = qualification;
Major = major;
University = university;
Country = country;
YearAttended = yearAttended;
Grade = grade;
}
}
"B.A", "Science",
"Lincoln University",
"United States",
"2001", "Excellent"));
//Add the third Education object into ListView item
listView.Items.Add (new Education (
"M.B.A", "Business",
"Chicago University",
"United States",
"2003", "Excellent"));
//Add the fourth Education object into ListView item
listView.Items.Add (new Education (
"PhD", "Science",
"Columbus University",
"United States",
"2007", "Excellent"));
}
comboBoxState.Items.Add ("Kentucky");
comboBoxState.Items.Add ("Mississippi");
comboBoxState.Items.Add ("Nevada");
comboBoxState.Items.Add ("New York");
comboBoxState.SelectedIndex = 0;
//Add 1 items into comboBoxCountry control
comboBoxCountry.Items.Add ("United States");
//Set default select item on ComboBoCountry control
comboBoxCountry.SelectedIndex = 0;
//Call DataBindingToListView method
DataBindingToListView ();
}
Of course, to fill full data as above picture, you must implement the Binding for
each GridViewColumn via DisplayMemberBinding property as follows.
Note: The links below are provided for further information of ADO.NET
definition: https://docs.microsoft.com/en-
us/dotnet/framework/data/adonet/ado-net-overview
1. ADO.NET Objects
ADO.NET separates data access from data manipulation into discrete
components that can be used separately or in tandem. Below is a screenshot of
how the ADO.NET components look like.
.NET Framework Data Provides data access for Microsoft SQL Server.
Provider for SQL Server Uses the System.Data.SqlClient namespace.
.NET Framework Data For data sources exposed by using OLE DB.
Provider for OLE DB Uses the System.Data.OleDb namespace.
.NET Framework Data For Oracle data sources. The .NET Framework
Provider for Oracle Data Provider for Oracle supports Oracle client
software version 8.1.7 and later, and uses the
System.Data.OracleClient namespace.
.NET Framework Data Provides data access for Microsoft SQL Server
Provider for SQL Compact 4.0. Uses the System.Data.SqlServerCe
Server Compact 4.0. namespace.
Object Description
The DataSet object can also be used independently of a .NET Framework data
provider to manage data local to the application or sourced from XML. The
following diagram illustrates the ADO.NET DataSet looks like.
DataSet
DataRelationCollection
ExtendedProperties
DataTableCollection
DataTable
DataRowCollection
DataView DataRow
ChildRelations
ParentRelations
Constraints
DataColumnCollection
ExtendedPropertie DataColumn
PrimaryKey ExtendedProperties
Noticed that if you working with SQL Server database platform, you can use
System.Data. SqlClient namespace, SqlConnection, SqlCommand,
SqlDataAdapter and SqlDataReader classes.
Please aware that EmployeeId is primary key and IDENTITY (1, 1), the
EmployeeId property is looks like.
Once you created ERP database and its tables, the below demonstration will
showcase a layout for the manipulation data in SQL Server Express LocalDB.
Firstly, let's perform the following steps to achieve this.
Secondly, you will create Employee class to store list of column data then fill into
List<> object as shown below.
Finally, you can use SqlConnection object with Connection String for SQL Server
Express LocalDB as example below.
To query data from LocalDB, you need to create Get method in Employee class
by using SqlCommand and SqlDataReader objects along with SELECT query as
follows.
{
EmployeeId = dataReader.GetInt32 (0),
FirstName = dataReader.GetString (1),
LastName = dataReader.GetString (2),
DateOfBirth = dataReader.GetDateTime(3),
Address = dataReader.GetString (4),
Telephone = dataReader.GetString (5),
Cellphone = dataReader.GetString (6),
Email = dataReader.GetString (7),
}
);
}
}
catch (Exception)
{
// handle something from Error object
}
//Call Return an Employee collection object
return Employees;
}
In order to read the data in Employees table and fill to ListView control, you can
create code to call Get method in buttonDisplay_Click handle event as example
below.
Once you make the above changes, run project then click Display button and you
will see the following output.
You can see how to edit information of an employee on WPF controls that you
can read from ERP database once select item by item on ListView control.
The following example describe code of the EditEmployee () method that called
in buttonEdit_Click method.
In fact, to read information of selected employee from Employees table you can
create Get method as follows.
}
}
}
return employee;
}
Then you can call Get method in EditEmployee method once the user Mouse
Double Click on ListView control. The following is an example of a case where
this applies.
Below is a screenshot of how the edit select employee’s information looks like.
Once you click Edit control, you can see the information of selected employee
attached into controls on the window as shown above. You can change any of
them and click Save button, data will update back to Employees table.
Let's look at examples of how we can implement these process via
buttonSave_Click method as follows.
DateOfBirth = (DateTime)
DateOfBirth.SelectedDate,
Telephone = textBoxTelephone.Text,
Cellphone = textBoxCellphone.Text,
Email = textBoxEmail.Text
};
// Set databasePath for DatabasePath property
employee.DatabasePath = databasePath;
// Update Employee object based on EmployeeId
if (labelId.Content != null && labelId.Content.ToString () != "")
{
employee.EmployeeId =
Convert.ToInt32 (labelId.Content);
// Call Update method in Employee class
if (employee.Update (employee))
MessageBox.Show ("Updated employee");
else
MessageBox.Show ("Failed to update employee!");
}
}
catch (Exception ex)
{
MessageBox.Show (ex.Message);
}
}
The following example describe code of the Update () method in Employee class
that I have called in above example.
"@Address", employee.Address);
command.Parameters.AddWithValue(
"@Telephone", employee.Telephone);
command.Parameters.AddWithValue(
"@Cellphone", employee.Cellphone);
command.Parameters.AddWithValue(
"@Email", employee.Email);
//Call ExecuteNonQuery method to execute query
isUpdated = command.ExecuteNonQuery ()>0;
}
}
return isUpdated;
}
If the above steps are followed, now run project and you will get the below output
in Visual Studio.
1 3
After change “Air Astana“ to “101 Air Astana NY” and click Save button, now
data is updated in ERP database. Below is a screenshot of how the Save action
looks like.
If the above steps are followed, you click Display button again and you will get the
new Address the below output in Visual Studio.
By clone the Get () method or Update () method and name is Delete (), you will
get the following output.
{
//Initializes the SqlConnection object with specific connection string
using (SqlConnection connection = new
SqlConnection (DatatabasePath))
{
//Call Open method to open a connection
connection.Open ();
//Here is INSERT statement
string commandText = @"DELETE Employees (
WHERE EmployeeId= @EmployeeId;";
//Initiate SqlCommand object
SqlCommand command = new
SqlCommand (commandText, connection);
//Pass value to parameter via AddWithValue
command.Parameters.AddWithValue (
"@EmployeeId", employeeId);
//Call ExecuteNonQuery method to execute query
isDeleted = command.ExecuteNonQuery ()>0;
}
}
return isDeleted;
}
Once you clone the above method, now you can call Delete () method in
buttonDelete_Click method. Here is the following example.
Once you select item on ListView control and click Delete button, a confirmation
dialog will display as follows.
4
2
1 3
If you click Yes button the selected employee will be deleted in database and new
data will refresh as below.
By clone the Update () method and name is Add () you will get the following
output.
"@Address", employee.Address);
command.Parameters.AddWithValue (
"@Telephone", employee.Telephone);
command.Parameters.AddWithValue (
"@Cellphone", employee.Cellphone);
command.Parameters.AddWithValue (
"@Email", employee.Email);
//Call ExecuteNonQuery method to execute query
isSaved = command.ExecuteNonQuery ()>0;
}
}
return isSaved;
}
Once you copy the above method, now you can call Add () method in
buttonSave_Click method. Here is the following example.
If the above steps are completed, you will run project and get the below output in
Visual Studio.
1
Professional WPF and C# Programming edXBooks 4.0 Express
Chapter 8: ADO.NET and CRUD 209
After adding new employee success, you can click Display button and new
employee is appearing as follows.
1. Entity Framework
Entity Framework (EF) is an open source object-relational mapping (ORM)
framework for ADO.NET (EF belong to ADO.NET family). It was a part of
.NET Framework and designed from the scratch as a lightweight, flexible, and
extensible ORM system.
It further enables developers to build a variety of applications by targeting various
platforms, devices, and deployment.
Note: The links below are provided for further information of Entity Framework
definition: https://docs.microsoft.com/en-us/ef/
But since Entity framework version 6 it is separated from .NET framework, they
are Entity Framework and Entity Framework Core.
Note: The links below are provided for further information of EF Core
definition: https://docs.microsoft.com/en-us/ef/core/
Entity Framework 6
o As an O/RM, Entity Framework 6 reduces the impedance
mismatch between the relational and object-oriented worlds,
enabling developers to write applications that interact with data
stored in relational databases using strongly-typed .NET objects
that represent the application's domain, and eliminating the need
for a large portion of the data access "plumbing" code that they
usually need to write.
o EF6 runs on the .NET Framework 4.x, which means it runs only
on Windows.
o EF6 continues to be a supported product, and will continue to see
bug fixes and minor improvements.
Note: The links below are provided for further information of new EF Core
definition: https://docs.microsoft.com/en-us/ef/efcore-and-ef6/index
Microsoft is making EF 7 available. EF7 will be the next major release of Entity
Framework.
2
1
Select ADO.NET Entity Data Model and enter name is ERPModel and then click
Add button, the next window is as shown below.
To use available database in project or any SQL Server database, you must select
“EF Designer from database” option, and then click Next button, next window is
shown as follows.
To select available ERP database in project or any SQL Server database by click
“New Connection” button, enter key for storing the connection string in
App.config file and then click Next button.
You must make sure database objects to be used in your solution checked as
shown above. Otherwise, these objects are unchecked. Keep model name is
ERPModel and click Finish button.
Here is picture shows EF assemblies adding to the References dialog.
Here is picture shows an ADO.NET Entity Data Model for managing a ERP
database schema.
Following picture showcases a diagram for the two classes are corresponding to
Employees and States tables in ERP database.
Click “Update” button on tool bar and here is something you have received from
the Visual Studio.
Click “Update Database” button to update table schema and open New Query
window for update value for StateCode column, UPDATE statement as shown in
follows.
The "New Query" will be opened for entering the following SQL statement.
To synchronize new column in Employees table to Entity Data Model, you can
Right click and select “Update Model from Database” as shown in follows.
The "Update Wizard" will be opened and you can see list of database objects as
shown in follows.
Click Finish button to update database objects and then you can see new changes
with Employee and State classes are shown in Entity Data Model diagram as
follows.
You should be aware that the current project is copied from previous section, now
you can add ComboBox control and nam is comboBoxStates, XAML code will
look like this.
If you follow all of the above steps, you will get the following layout.
Firstly, look at the buttonDisplay_Click event handler, the code below will
complite and work properly if you rewrite it to look like this.
Here is picture shows the result of running the program in above example.
Now, explore an example for binding data from States table into the
SelectedValuePath and DisplayMemberPath properties of comboBoxStates
control are described in XAML code as follows.
Here is picture shows the result of running the program in above example.
This section is designed to focus simple LINQ syntax by encouraging you to learn
and explore about a line of code for combining the lambda expression in LINQ.
Note: The links below are provided for further information of LINQ and
Lambda expression: https://docs.microsoft.com/en-
us/dotnet/csharp/programming-guide/statements-expressions-
operators/lambda-expressions
Here is source code of the LINQ with Lambda expression to get information of
specific Employee based on employee id.
To get value for passing to EditEmployee method while press left mouse button
on ListView control or click on Edit button, you continue to create the
MouseDoubleClick event handler and buttonEdit_Click event handler of Edit
button, and here is example looks like.
Based on SingleOrDefault () method with Lambda expression, you can get exactly
the record of specific employee as follows.
If you follow all of the above steps and run your program in Visual Studio, you
will get the following output.
1 3
Looking at the screenshot in edit window, you can see the information of
employee id 3, you can change email to "[email protected]", address to
"223 E. Concord Street, Orlando, FL 32801” and state to Florida.
3
3 3
4
1 2
After clicked the Save button, you can see new changes as following picture.
Below picture shows a complete execution of a UPDATE action and you can see
C# code as follows.
buttonSave_Click – C# Code
void buttonSave_Click (object sender, RoutedEventArgs e)
{
try
{
//Initializes the Entity Data Model name ERPEF
using (ERPEF entity = new ERPEF ())
{
// UPDATE case based on hidden value of labelId
if (labelId.Content != null &&
labelId.Content.ToString() != "")
{
// Get employee id from hidden value of labelId
int employeeId = Convert.ToInt32(labelId.Content);
// Get specific employee based on value of labelId
var employee =
entity.Employees.SingleOrDefault(
n => n.EmployeeId == employeeId
);
// Update new value to properties of employee
employee.FirstName = textBoxFirstName.Text;
employee.LastName = textBoxLastName.Text;
employee.Address = textBoxAddress.Text;
employee.DateOfBirth= DateOfBirth.SelectedDate;
employee.Telephone = textBoxTelephone.Text;
employee.Cellphone = textBoxCellphone.Text;
employee.Email = textBoxEmail.Text;
employee.StateCode = Convert.ToString
(comboBoxStates.SelectedValue);
// Call SaveChanges method of DbContext object
if (entity.SaveChanges () > 0)
MessageBox.Show ("Success to update!");
else
{
MessageBox.Show ("Failed to update employee
or nothing changes!");
}
}
}
catch (Exception ex)
{
MessageBox.Show (ex.Message);
}
The SaveChanges method return the integer number, If the return value is greater
than 0, then at least one object is successfully updated. Otherwise, failed updated.
In the above list window, you can see the list of employees are displayed. So, you
can select an employee and click the Delete button, a confirmation dialoge will
show up and wait for your selection.
Here is scenario I have selected an employee from the above window.
1 3
4
Click Yes button, employee number 3 will be deleted and you can see new list of
employee as follows.
Let's look at examples of how we can implement C# code in Click event handler
for delete employee in database.
buttonDelete_Click - C# Code
void buttonDelete_Click (object sender, RoutedEventArgs e)
{
//Get selected employee from ListView control
Employee employee =
(Employee)listViewData.SelectedItem;
if (employee != null &&
MessageBox.Show("Are you sure to delete?", "?",
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
//Initializes the Entity Data Model name ERPEF
using (ERPEF entity = new ERPEF ())
{
// Get selected employee id base on hidden control
int employeeId = Convert.ToInt32(labelId.Content);
// Get selected employee based on Lambda expression
employee = entity.Employees.SingleOrDefault (
n => n.EmployeeId == employeeId
);
//Selete employee from EF object model
entity.Employees.Remove(employee);
// Save changes of EF object model by calling
// the SaveChanges method
if (entity.SaveChanges()>0)
{
MessageBox.Show ("Success to delete employee");
buttonDisplay_Click (sender, e);
//Can reset employee data on edit window
buttonAdd_Click (sender, e);
}
else
MessageBox.Show ("Failed to delete employee!");
}
}
}
How to ensure the data deleted on edit window is only reset empty for the WPF
controls? Here is example shows how to do it and make sure you call this method
in case of successful delete.
buttonAdd_Click – C# Code
void buttonAdd_Click (object sender, RoutedEventArgs e)
{
labelId.Content = "";
textBoxFirstName.Text = "";
textBoxLastName.Text = "";
textBoxAddress.Text = "";
DateOfBirth.SelectedDate = null;
textBoxTelephone.Text = "";
textBoxCellphone.Text = "";
textBoxEmail.Text = "";
comboBoxStates.SelectedValue = null;
}
Following the section of update an employee in database, you can add code snippet
for adding new an employee in buttonSave_Click event handler.
The following is an example of a case where this applies.
buttonSave_Click – C# Code
void buttonSave_Click (object sender, RoutedEventArgs e)
{
try
{
//Initializes the Entity Data Model name ERPEF
using (ERPEF entity = new ERPEF ())
{
if (labelId.Content != null &&
labelId.Content.ToString() != "")
{
//Case of update selected employee
}
else
{
// Case of add new employee
var employee = new Employee ()
{
//Add value to employee from controls
FirstName = textBoxFirstName.Text,
LastName = textBoxLastName.Text,
Address = textBoxAddress.Text,
DateOfBirth = DateOfBirth.SelectedDate,
Telephone = textBoxTelephone.Text,
Cellphone = textBoxCellphone.Text,
Email = textBoxEmail.Text,
StateCode = Convert.ToString(
comboBoxStates.SelectedValue)
};
//Add new employee object into Entity model
entity.Employees.Add (employee);
//Update changes of Employees into database
if (entity.SaveChanges () > 0)
MessageBox.Show(
"Success to add new employee!");
else
{
MessageBox.Show(
"Failed to add new employee
or duplicate data!");
}
}
}
}
catch (Exception ex)
{
MessageBox.Show (ex.Message);
}
}
If you follow all of the above code snippet and run your program in Visual Studio,
you will get the following output.
After fulfill data on controls and if the Save button is clicked, a dialog will be
displayed as below.
To see new changes, click Display button and here is the new window shows this
employee.
1 2
In case of refresh the list of employees on ListView control, you can call
buttonDisplay_Click method in buttonSave_Click event handler.
Moreover, you also call buttonAdd_Click method in buttonSave_Click event
handler. The following is an example of a case where this applies.
buttonSave_Click – C# Code
void buttonSave_Click (object sender, RoutedEventArgs e)
{
try
{
//Initializes the Entity Data Model name ERPEF
using (ERPEF entity = new ERPEF ())
{
if (labelId.Content != null &&
labelId.Content.ToString() != "")
{
//Case of update employee into database
…
//Update changes of Employees into database
if (entity.SaveChanges () > 0) {
MessageBox.Show(
"Success to update employee!");
//Reset data on controls
buttonAdd_Click (sender, e);
//Refresh changes of data from database
buttonDisplay_Click (sender, e);
}
else
{
MessageBox.Show("Failed to update employee
or nothing changes!");
}
}
else
{
// Case of Add new employee into database
…
//Update changes of Employees into database
if (entity.SaveChanges () > 0) {
MessageBox.Show(
"Success to add new employee!");
//Reset data on controls
buttonAdd_Click (sender, e);
//Refresh changes of data from database
buttonDisplay_Click (sender, e);
}
else
{
MessageBox.Show(
"Failed to add new employee
or duplicate data!");
}
}
}
}
catch (Exception ex)
{
MessageBox.Show (ex.Message);
}
}
Notice that the current project is copied from previous section and now let's
perform the following steps to illustrate how to manipulate data by using Entity
Data Model and grouping on ListView control.
Prepare for displaying the list of employees in Employees table, you can add
example as follows.
buttonDisplay_Click – C# Code
private void buttonDisplay_Click (object sender, RoutedEventArgs e)
{
try {
//Initializes the Entity Data Model name ERPEF
using (ERPEF entity = new ERPEF ()) {
//Get all employees Entity model and fill to ListView control
listViewData.ItemsSource =
entity.Employees.ToList ();
}
}
catch (Exception ex)
{
MessageBox.Show (ex.Message);
}
}
By clicking Search button in this window, you have displayed the all employees in
Employees table and here is picture shows the result of running the default
program in above example.
To sort and filter the data in a ListView control; you can use LINQ method syntax
and Lambda expression as follows.
And now let's key in any string to the keyword textbox and click search button to
filter data as following illustration.
1 2
In case of both keyword and state name are selected, you can see the different list
as follows.
1 2 3
To group, sort, and filter the data in a ListView control; firstly, you can bind it to
a CollectionView that supports these functions in WPF, and you can then work
with this data collection in the CollectionView without affecting the underlying
source data as follows.
CollectionView – C# Code
void buttonDisplay_Click (object sender, RoutedEventArgs e)
{
try {
//Initializes the Entity Data Model name ERPEF
using (ERPEF entity = new ERPEF ()) {
IQueryable<Employee> employees =null;
string state = Convert.ToString(
comboBoxStates.SelectedValue).Trim() ;
string keyword = textBoxKeyword.Text;
//If user has entered the keyword or selected state
if (keyword != "" || state != "")
{
//Use LINQ Method syntax for filtering data
employees = entity.Employees.
Where (n => (keyword !="" &&
(n.FirstName.Contains (keyword)
|| n.LastName.Contains (keyword)))
|| keyword == "").
Where (n => state == ""
|| (state != "" &&
n.StateCode.Equals (state )));
}
else
{
//Get all employee objects in Entity model
employees = entity.Employees;
}
//Bind employees Queryable into ListView control
//listViewData.ItemsSource=employees.ToList ();
//Get employees collection by using CollectionView
CollectionView view = (CollectionView)
CollectionViewSource.GetDefaultView
(employees.ToList ());
//Grouping employees by using PropertyGroupDescription
PropertyGroupDescription groupDescription =
new PropertyGroupDescription ("StateCode");
view.GroupDescriptions.Add (groupDescription);
//Bind CollectionView object into ListView control
listViewData.ItemsSource = view;
}
}
catch (Exception ex)
{
MessageBox.Show (ex.Message);
}
}
Secondly, add GroupStyle property into ListView under XAML code as follows.
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
Of course the Name and ItemCount attributes are fixed name and provided by
PropertyGroupDescription object, unless you want to display State name in each
list item.
If you follow all of the above steps and run your program in Visual Studio, you
will get data grouping as the following output.
The above scenario is designed to focus simple LINQ Method syntax and Lambda
Expression by encouraging you to learn and explore about a line of code for
combining the grouping and filtering data.
Now, you can enter the name "Henry" in the Keyword box and click the Search
button, here is picture shows this result.
1 2
If you want to show and group data on the different view, you can use DataGrid
control instead of ListView control.
Now, you need to copy WpfAppGroupByAndFilterByListView project and name
WpfAppGroupByAndFilterByGridView as follows.
Next you have added new column IsActivated BIT default 0 in Employees schema
as following picture.
Click Update button and confirmation dialoge will show up and wait for your
selection as follows.
Click “Update Database” button to update table schema, and then execute
UPDATE statement for update value 0 for this column as follows.
To use new column in Entity Data Model, you need to update diagram as follows.
Here is the picture shows a complete update action and you can see new change
of table schema along with data as follows.
This section is also designed to use Entity Data Model and LINQ syntax by using
familiar snippet code in previous project.
Here is something familiar you will have received from above example.
If you need to illustrate how the groups as follows. You can use setting the
GroupStyle to something like the following XAML snippet.
TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock
Text="{Binding Name}"/>
<TextBlock Text=": " />
<TextBlock
Text="{Binding ItemCount}"/>
<TextBlock Text=" employee(s)"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
1
2
2. Multi Grouping
As the above example, adding grouping to the DataGrid control is very basic by
using XAML, what you need is understand and apply the GroupStyle with a
HeaderTemplate, then let the DataGrid knows how to render data as a group.
Off course, you need to add a few code snippets of Code-behind to tell WPF
which property to group by such as State code column.
You have just read some examples described an above and known how to group
employees based on State code column. However, the DataGrid control also
supports multi grouping.
Here is copied project name WpfAppDataGridMultiGroups as follows.
To enable multi grouping you have to define a CollectionView that contains more
than one GroupDescription that defines the criterias how to group. Here is
example illustrates how to use CollectionView and GroupDescription to set the
mutli grouping as follows.
Above two groups look a bit more exciting, and they even include an expander
button on State code and IsActivated that will toggle the visibility of the group
items when you click it.
The DataGrid control also provides a feature that shows a detail panel for a
selected row. It can be enabled by setting a DataTemplate to
the RowDetailsTemplate attribute.
You can specify a RowDetailsTemplateSelector that selects a data template
according to the type or property that this row contains as example below.
</DataTemplate>
</DataGrid.RowDetailsTemplate>
You should be aware that the detail panel is displayed any type or data that Entity
Data Model contains. Here is example to illustrate how to bind the Photo or
Picture into the Image control.
As the above example, the data template gets the object that is bound to this row
passed by the DataContext and can bind to it. Here is a picture shows detail panel
once you select item.
2
1
Following the previous project, you need to add the new table name
FamilyRelations and update the Entity Data Model diagram as follows.
To prepare the sample data set for this table, you need to create some records as
follows.
One you make the above changes, and run the program in Visual Studio you will
see the following output.
Firstly, you can create an example for binding data from FamilyRelations table into
the RowDetailsTemplate of DataGrid control are described in XAML code as
follows.
RowDetailsVisibilityChanged – C# Code
void gridViewData_RowDetailsVisibilityChanged (object sender,
DataGridRowDetailsEventArgs e)
{
try
{
//If user select employee on DataGrid control
if (e.Row.DetailsVisibility == System.Windows.Visibility.Visible)
{
//Get selected item object from e argument
var item = e.Row.Item;
Type type = item.GetType ();
//Get selected employee id from item object
int employeeId = (int)type.GetProperty
("EmployeeId").GetValue(item, null);
If the above steps are followed, select the first employee and you will get family
relations as the below output.
1
2
As above sample data in the FamilyRelations table, the records are available for
employee id 1 and 2, so select employee id is 2 you can see result looks like this.
1. Edit Data
By copying WpfAppGroupByAndFilterByGridView project and name is
WpfAppGroupByAndFilterByGridView then use
If the above steps are followed, you will get the below picture in Visual Studio.
2. Update Data
Follwing above picture, if user change any information of employee, you can
directly get changed records by using ChangeTracker property of Entity Data
Model object.
Assumpt with this scenarios, you change something for employee as follows
1
2
4
5
Click Save button, you will be get popup window as follows. Click Yes button to
accept to update changed employee to database. Otherwise click Cancel button.
Suppose that you click Yes button, a dialog box should pop up which shows the
confirmation message as follows.
Click Yes to accept changes and SaveChanges method called then a next dialog
box will show the successful update.
One you make the above actions, and click Search button again, you will see newest
employees as the following output.
Note: The links below are provided for further information of Routed Events
definition: https://docs.microsoft.com/en-
us/dotnet/framework/wpf/advanced/routed-events-overview
Secondly, this should feel no different than hooking up events in Windows Forms
and ASP.NET app. Here are three examples show the three event handlers
associated with above buttons.
Finally, once you click each Button control, the the code-behind associate with
event handler is called and you can see the corresponding of text attached on the
window as shown below.
In other words, the event route for this Click event is Button-->StackPanel--
>Border-->Grid-->... Window.
Let's consider the following simple element tree which are copied from above
XAML example and modified the name of 3 buttons.
The above XAML code showcases an event handler for the three buttons are
corresponding to Yes, No and Cancel actions. Here are an example shows a routed
event handler associated with three buttons.
RoutedEvent_ClickHandler – C# Code
void RoutedEvent_ClickHandler (object sender, RoutedEventArgs e)
{
// Get FrameworkElement via Source of e argument.
FrameworkElement element =
e.Source as FrameworkElement;
// Basing on name of element argument,
// you can identify user’s action
switch (element.Name)
{
case "Yes":
MessageBox.Show("Yes Button");
// do more thing here for Yes option...
break;
case "No":
MessageBox.Show("No Button");
// do more thing here for No option...
break;
case "Cancel":
MessageBox.Show("Cancel Button");
// do more thing here for Cancel option...
break;
}
//To stop routing, you have to set e.Handled = true;
e.Handled = true;
}
Here are an example shows a routed event handler associated with Yes button.
Yes_Click – C# Code
void Yes_Click (object sender, RoutedEventArgs e)
{
// Just show the message.
MessageBox.Show("Bubbling event");
}
When you click No button, this buton has no event handler, it will travel up the
visual tree to the topmost element in the visual tree is StackPanel and
RoutedEvent_ClickHandler event handler called.
The following is a picture of a case where Bubbling routing event applies.
However, you click Yes button, this buton has Yes_Click event handler, it will call
this event first, and then continues to travel up the visual tree to the topmost
element in the visual tree and RoutedEvent_ClickHandler event handler also
called.
RoutedEvent_BaseClickHandler – C# Code
void RoutedEvent_BaseClickHandler (object sender, RoutedEventArgs e)
{
// Get FrameworkElement via Source of e argument.
FrameworkElement element =
e.Source as FrameworkElement;
// Basing on name of element argument,
// you can identify user’s action
switch (element.Name)
{
case "ButtonYes":
MessageBox.Show ("Button Yes");
// do more thing here for Yes option...
break;
case "ButtonNo":
MessageBox.Show ("Button No");
// do more thing here for No option...
break;
case "ButtonCancel":
MessageBox.Show ("Button Cancel");
// do more thing here for Cancel option...
break;
}
//To stop routing, you have to set e.Handled = true;
e.Handled = true;
}
Here are an example shows a routed event handler associated with ButtonYes
button.
ButtonYes_Click – C# Code
void ButtonYes_Click (object sender, RoutedEventArgs e)
{
// Just show the message.
MessageBox.Show ("Tunneling event");
}
The following is a picture of a case where Tunneling routing event applies.
Notice that the difference between the tunneling and bubbling event handlers are
a tunneling event will start at the highest node in the tree and going down to the
lowest child. In contrast, a bubbling event will start at the child and then go
upwards to the highest node.
tunneling event
bubbling event
Next, you add the bubbling routed event to DataGrid control and name is
BubblingRoutedEvent_Click as follows.
MessageBox.Show ("Delete");
//You can delete Employee object by using LINQ
break;
case "Notify":
//You can send email to employee via Email property
MessageBox.Show ("Notify");
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show (ex.Message);
}
}
One you make the above changes, and run the project you will see the following
output.
2 3
If you click Delete button, here is dialog shows the Delete string as follows.
In case of clicking Notify button, you will the dialog shown as follows.
Here is example shows C# code that uses to handle the button Click event.
{
//just do something
}
An application might allow a user to copy selected objects or text by either Ctrl+C
or select top menu is Edit->Copy or in context menu is right clicking - > Copy,
all three ways do the same result.
As above description, copy action has to be put in three different event handlers
but they are same logic.
Note: The links below are provided for further information of Commanding
definition: https://docs.microsoft.com/en-
us/dotnet/framework/wpf/advanced/commanding-overview
To make copy action simpler, you just associate these actions into a single
command with the logic in a single event handler by XMAL or Code-behind.
The command target is the object that the command is being executed on.
The command binding is the object which maps the command logic to the
command.
Commands in WPF are created by implementing the ICommand interface. In
other hands, the WPF implementation of ICommand is the RoutedCommand
class. ICommand exposes two methods, Execute, and CanExecute, and an event,
CanExecuteChanged.
Execute performs the actions that are associated with the command. The
Execute method on a RoutedCommand raises the PreviewExecuted and
the Executed events on the command target.
Properties Description
Close Gets the value that represents the Close command.
Delete Gets the value that represents the Delete command.
Find Gets the value that represents the Find command.
New Gets the value that represents the New command.
Open Gets the value that represents the Open command.
Save Gets the value that represents the Save command.
Print Gets the value that represents the Print command.
3. ApplicationCommands Class
Notice that the current project called WpfAppCommanding is copied from
WpfAppEntityFramework project and now let's perform the following steps to
illustrate how to save data by using Entity Data Model and Commands.
WPF supplies a set of common routed commands spread across several classes:
MediaCommands, ApplicationCommands, NavigationCommands,
ComponentCommands, and EditingCommands.
Note: the links below are provided for further information of Commands
definition: https://docs.microsoft.com/en-
us/dotnet/api/system.windows.input.applicationcommands?view=netframewor
k-4.8
In this section, I will reuse showcase the Click event for Save, Add New (associate
with New command), Delete, Edit (associate with Open command), Display
(associate with Find command), Print and Close buttons as table below.
Now, let's perform the following steps to achieve CommandBinding for Display,
Save and Delete buttons.
Firstly, you will create bindings for the commands just as for the application
commands by using CommandBinding, here is example shows commands for
Find as follows.
As already explained, current project is copied from available project, you just
rename the buttonDisplay_Click event handler method to DisplayData method
and what you do is call this method in ExecuteFind method.
In this case, now buttonDisplay_Click event handler method is DisplayData
method as follows.
Revises some code snipset is really simple and once you've done it, you can use
your own commands just replace Click event by Command in XAML code.
The following is an example of using command where buttonDisplay button
applies.
Finally, one you define the above examples, and run the program in Visual Studio
you will see the following screenshot.
if (entity.SaveChanges() > 0)
MessageBox.Show(
"Success to update employee!");
else
{
MessageBox.Show("Failed to update employee
or nothing changes!");
}
}
else
{
//Initializes new employee and fill value to properties
var employee = new Employee ()
{
FirstName = textBoxFirstName.Text,
LastName = textBoxLastName.Text,
Address = textBoxAddress.Text,
DateOfBirth = DateOfBirth.SelectedDate,
Telephone = textBoxTelephone.Text,
Cellphone = textBoxCellphone.Text,
Email = textBoxEmail.Text,
StateCode = Convert.ToString(
comboBoxStates.SelectedValue)
};
//Call Add method to add new employee into Entity Data Model
entity.Employees.Add(employee);
//Call SaveChanges method to save new employee
// to ERP database, success if return number grater than 0
if (entity.SaveChanges() > 0)
MessageBox.Show (
"Success to add new employee!");
else
{
MessageBox.Show ("Failed to add new
employee or duplicate data!");
}
}
}
}
catch (Exception ex)
{
MessageBox.Show (ex.Message);
}
}
Instead of validating the required input for columns that are not allowed null in
the database, you can specify the logical expression in CanExecuteSave method as
follows.
<Button
x:Name="buttonSave"
Command="Save"
Content="Save"
HorizontalAlignment="Left"
Margin="174,121,0,0"
VerticalAlignment="Top"
Width="90" Height="34"
/>
If the above steps are followed, run project and you will enter some information
for new employee as the below output.
Click Save button, it will call SaveData method which takes values from controls
through Entity Data Model and save into Employees table in ERP database.
You will have received a dialog from above example if it’s successfully inserted.
By clicking OK button to close this dialog and continue click Display button after
then, you have see an added employee as follows.
In order to apply commanding for Delete action, you first redesign layout as shown
in below picture.
To add a ContextMenu control to ListView control, you just write XAML code
right after ListView.View as shown below.
To embed a Button control in ListView control, you can use CellTemplate and
DataTemplate as described in below example.
</GridViewColumn.CellTemplate>
</GridViewColumn>
Then you need to create the can execute handler is CanExecuteDelete method as
example below.
{
e.CanExecute = listViewData.SelectedItem != null ;
}
As mentioned, if you are selected a row this buttonDelete and DeleteButton are
enabled. Otherwise they are disabled.
);
//Remove specific an employee out of Entity Data Model
entity.Employees.Remove (employee);
//Call SaveChanges method to update new changes
return (entity.SaveChanges() > 0);
}
}
Then you need to create the execute handler is ExecuteDelete method as example
below.
{
//Remove specific an employee out of Entity Data Model
if (DeleteById (employee.EmployeeId))
{
MessageBox.Show
("Success to delete employee");
//Reload the list of Employees from Entity Data Model
DisplayData ();
}
else
MessageBox.Show
("Failed to delete employee!");
};
}
Once you make the above changes, then click Display button and Right clicking
on ListView control you will see the following output.
2 2
The combination of Command for Delete action allows you do not care to
dertimine what control was selected, a confirmation dialoge will show up and wait
for user’s selection.
Once Yes button is cliecked, selected employee 33 will be removed out database
and you can click Display button to see new changes.
As you have created the examples of using the CommandBinding for Display, Save
and Delete buttons. So if you want to define the Command for Edit button, you
can apply same way from Delete button.
Familiar with Delete or Edit buttons, in order to apply commanding for Print
action, you add button name is buttonPrint as shown in below picture.
Executed="ExecutePrint"
CanExecute="CanExecutePrint"
/>
Next, you need to create the can execute handler is CanExecutePrint method as
example below.
1 2
The above example is compiled successfully; you must add the ExecutePrint
method as follows.
}
}
}
As you have created the examples of using the CommandBinding for Display,
Save, Delete and Print buttons. So if you want to define the Command for Edit
button, you can apply same way from Delete button.
4. Export Command
If the commands in the command library classes do not meet your needs, then you
can create your own commands. In order to create custom Commands, you can
inherit above project then name is WpfAppCustomCommanding like this.
The first is to start from the ground up and implement the ICommand
interface.
1 2
Note: The links below are provided for further information of Custom
Commands definition: https://docs.microsoft.com/en-
us/dotnet/framework/wpf/advanced/commanding-
overview?view=netframework-4.8#creating_commands
Start a simple implementation of ICommand, you can create the new class and
name is ExportCommand then use an intelligent unitlty in Visual Studio to
generate default event handler as following example.
However, default CanExecute or Execute method not allows you to have a logic
for exporting data. So, you need to modify code for an Export functionality.
Learning the definition of ApplicationCommands class, for CanExecute method
you need to implement arguments and body as in the following.
For Execute method, you need to implement arguments and body as in the
following.
Now, you can point a Button or MenuItem at any ICommand with the Command
property
Here is an example shows code that uses above Export instance for Export button
control by specifying the StaticResource.
Note: The links below are provided for further information of Document
definition: https://docs.microsoft.com/en-
us/dotnet/framework/wpf/advanced/documents-in-wpf
WPF also provides integrated services for document display, packaging, and
security. WPF divides documents into two broad categories based on their
intended use; these document categories are termed "fixed documents" and "flow
documents."
The .NET Framework provides a set of pre-built controls that simplify using fixed
documents, flow documents, and general text within your application.
To use fixed documents, flow documents classes, you need to Add Reference and
in the Add Reference dialog box, choose ReachFramework as follows.
1. What is FixedDocument?
The Fixed documents are intended for applications that require a precise (exactly)
"what you see is what you get" presentation, independent of the display or printer
hardware used such as XPS, PDF or Word documents.
Content Viewing
Text Search
Add Button control and use an OpenFileDialog to browse a file, get its name and
load its content into a DocumentViewer control.
openFileDialog.Filter =
"XPS files (*.xps)|*.xps|PDF files (*.pdf)|*.pdf";
// Launch OpenFileDialog by default folder is bin/debug/
openFileDialog.InitialDirectory =
Environment.CurrentDirectory;
// Calling ShowDialog method
Nullable<bool> result = openFileDialog.ShowDialog();
if (result == true)
{
// Get the selected file name
ShowDocument (openFileDialog.FileName);
}
Note: For WPF, you will find standard dialogs for both opening and saving files
in the Microsoft.Win32 namespace.
An XML Paper Specification (XPS) document is a document format you can use
to view, save, share, digitally sign, and protect your document’s content. You can
create XPS file by “Save as type” in Microsoft office.
An XPS document is like an electronic sheet of paper: You can’t change the
content on a piece of paper after you print it, and you can’t edit the contents of an
XPS document after you save it in the XPS format.
Let’s see what the code for that requires.
}
Now, if you run the application and browse a Xps file such DocumentsInWPF.xps
looks like
You can see two pages on screen by click on “Two Pages” button on tool bar or
press Ctrl+4.
You also can load and print the word document by convert to Xps document as
example below.
doc.PageSetup.PaperSize = WdPaperSize.wdPaperA4;
try
{
//Save Word document to Xps Document
doc.SaveAs(xpsDocumentName, WdSaveFormat.wdFormatXPS);
wordApplication = null;
XpsDocument xpsDoc = new XpsDocument (xpsDocumentName,
System.IO.FileAccess.Read);
return xpsDoc;
}
catch (Exception ex)
{
string errorMessage = ex.Message;
}
return null;
}
One you make the above changes, and run the program in Visual Studio you will
see the following output.
After converted word document to Xps document, you can see out look like.
Hosts a portable, high fidelity, fixed-format document with read access for user
text selection, keyboard navigation, and search.
Note: The links below are provided for further information of FixedDocument
class definition: https://docs.microsoft.com/en-
us/dotnet/api/system.windows.documents.fixeddocument?view=netframework-
4.7.2
Here is source code of using the FixedDocument class of loading the Text file
name DocumentsInWPF.txt which store in bin/Debug folder.
textBlock.TextWrapping = TextWrapping.Wrap;
textBlock.Width = fixedPage.Width - 100;
textBlock.Text = content;
fixedPage.Children.Add (textBlock);
((System.Windows.Markup.IAddChild)pageContent).
AddChild (fixedPage);
fixedDocument.Pages.Add (pageContent);
documentViewer.Document = fixedDocument;
}
If the text document contains two pages of text, here is source code of using the
FixedDocument class of loading the Log file name DocumentsInWPF.log which
store in bin/Debug folder.
fixedPage.Height = fixedDocument.DocumentPaginator.PageSize.Height;
textBlock.TextWrapping = TextWrapping.Wrap;
textBlock.Width = fixedPage.Width - 100;
In the output, you can see that the window is displayed and the text now are
displayed two pages on the it.
Note: It is really bad solution if you use FixedDocument class for loading Text
file instead of using FlowDocument class.
2. What is FlowDocument?
Hosts and formats flow content with advanced document features, such as
pagination and columns.
FlowDocument enforces a strong content model for child content. Top-level child
elements contained in a FlowDocument must be derived from Block.
Note: The links below are provided for further information of FlowDocument
class definition: https://docs.microsoft.com/en-
us/dotnet/api/system.windows.documents.flowdocument?view=netframework-
4.7.2
By using FlowDocument class, you can read Text file and display its content on
FlowDocumentReader control. Here is example for using FlowDocument class to
read DocumentsInWPF.txt file in bin/Debug folder.
If the above steps are followed, you will get the below output in Visual Studio.
{
//Initializes the Paragraph object
Paragraph paragraph = new Paragraph ();
//Read file content and assign to paragraph object
paragraph.Inlines.Add (
System.IO.File.ReadAllText (fileName));
//Assign paragraph object into FlowDocument object
FlowDocument document = new FlowDocument (paragraph);
//Assign FlowDocument object into document viewer control
documentViewer.Document = document;
}
Below is a screenshot of how the FlowDocumentScrollViewer control looks like.
Note: The links below are provided for further information of Drag and Drop
infrastructure: https://docs.microsoft.com/en-
us/dotnet/framework/wpf/advanced/drag-and-drop-overview
Drag-and-drop operations typically involve two parties: a drag source from which
the dragged object originates and a drop target which receives the dropped object.
The drag source and drop target may be UI elements in the same application or a
different application. The type and number of objects that can be manipulated
with drag-and-drop is completely arbitrary.
For example, files, folders, and selections of content are some of the more
common objects manipulated through drag-and-drop operations.
Step 2. Find the data you want to drag and create a DataObject that
contains the format, the data and the allowed effects, such as Data of WPF
Controls, File or Folder, HTML…
Step 4. Set the AllowDrop property to True on the elements you want to
allow dropping.
Step 6. When the user releases the mouse button the DragDrop event is
called.
o Get the data by calling the GetData () method on the Data object
provided in the event args argument.
o Add this data to WPF Controls.
2. Data Transfer
Drag-and-drop is part of the more general area of data transfer. Data transfer
includes drag-and-drop and copy-and-paste operations.
A way to temporarily
store the transferred data.
3. Drag-and-Drop Events
Drag-and-drop operations support an event driven model. Both the drag source
and the drop target use a standard set of events to handle drag-and-drop
operations.
This event occurs when an object is dragged into the drop target's boundary. This
is so-called a bubbling event.
To start the drag operation, we have to detect a mouse move while the left mouse
button is pressed.
This event occurs when an object is dropped on the drop target. This is a bubbling
event.
To make an element be a drop location, set the AllowDrop property to true.
When the user drags an item over the element, the DragEnter event is
called.
In this event you can analyze the data and decide if a drop is allowed or
not.
When the user releases the mouse button the Drop event is called.
The DragEnter event occurs when the data is dragged into the drop
target's boundary.
The DragOver event occurs continuously while the data is dragged over
the drop target.
The DragLeave event occurs when the data is dragged out of the target's
boundary without being dropped.
The Drop event occurs when the data is dropped over the drop target.
The data itself can consist of anything that can be represented as a base Object.
The corresponding data format is a string or Type that provides a hint about what
format the data is in. Data objects support hosting multiple data/data format pairs;
this enables a single data object to provide data in multiple formats.
Let's look at examples of how we can implement the Drag and Drop operations
and their events for ListView control as follows.
Here is a source code of the C# to determine the Drop event by using DataObject
object if the folder name or file name are dropped on area of ListView control.
Familiar Drop event, here is a source code of the C# to determine the DragEnter
event by using DataObject object if the folder name or file name are dragged over
area of ListView control.
{
e.Effects = DragDropEffects.None;
}
}
}
}
By select any folder or file from your Windows Explorer and drag then drop on
this window.
If the above steps are followed, you will get the below output in Visual Studio.
Note: You can use Drag and Drop operations with their events to allow the user
drag and drop Video, Music or Image file to Image or MediaElement controls
In Chapter 6 section service-based database, you can follow the steps to reuse the
service-based database, by copy ERP.mdf into your project as an output.
Then, you can open View menu and select Server Explorer and below is a
screenshot of how the database structure looks like.
You will see the States table that to store the list of states as follows.
Following the section of service-based database, you can create ADO.NET Entity
Data Model for connecting ERP database.
Now, you will also create a small application that contains two ListBox controls to
test the drag-and-drop functionality.
Once you add two ListBox controls to the window, you can see the ListBox
controls embedded on the window as shown below.
Allow fill list of states into these ListBox controls, you need to add properties in
XAML as follows.
SelectedValuePath="Abbreviation"
AllowDrop="True"
DragEnter="listBox2_DragEnter"
Drop="listBox2_Drop" />
</Grid>
Next, you create C# code to fill list of states into two ListBox controls from the
Window_Load handler event.
If you follow all of the above methods and run your program, you will get the
following output.
Allow user to drag from one item in the left ListBox control to right ListBox
control, you can create C# code in PreviewMouseLeftButtonDown event as
follows.
data = source.ItemContainerGenerator
.ItemFromContainer (element);
if (data == DependencyProperty.UnsetValue)
{
element = VisualTreeHelper.GetParent (
element) as UIElement;
}
if (element == source)
{
return null;
}
}
if (data != DependencyProperty.UnsetValue)
{
return data;
}
}
return null;
}
Looking back the Drop action for the right ListBox control which you can see
them in above section, you need to write method for Drop event as follows.
}
}
For the DragEnter operation, how to ensure the data pulled to the right ListBox
control is only taken from the left ListBox control. Here is C# code in the
DragEnter example looks like.
If you follow all of the above four methods and run your program, select one state
on the left ListBox control and drag then drop on the second ListBox control, you
will get the following output.
The following illustration show case of the duplicate many times due to not
checked before dropping the data to the right ListBox control, especially one state
that adds more than two times.
Making sure only one State is added to the right ListBox control, you can change
above example of Drop event as follows.
Note: In case of drag and drop object from a ListBox control to a TextBox, you
can follow above steps.
Dependency property represents a property that can be set through methods such
as styling, data binding, animation, and inheritance by using XAML or code.
CLR properties can directly read/write from the private member of a class by using
getter and setter. CLR properties are stored in local object.
Here is something you have received from the basic of Object Oriented
Programming.
Dependency Properties offer a lot of functionalities that you won’t get by using a
CLR property. In contrast with CLR Properties, they are not stored in local object
instead of stored in a dictionary of key/value pairs which is provided by the
DependencyObject class. So, it saves a lot of memory because it stores the
property when changed.
Here is example uses the ItemsSourceProperty dependency property using for
ListBox control.
In this case, you need to create the method GetDataTable which return the
ADO.NET DataTable object. Here is looks like.
Moreover, you also add ListBox and Button controls to MainWindow and XAML
code looks like.
/>
<Button
x:Name="button1" Content="Button"
Grid.Column="1" Margin="10,10,0,0"
HorizontalAlignment="Left" Grid.Row="1"
VerticalAlignment="Top" Width="100"
Height="25" Click="button1_Click"
/>
If the above steps are aboved, you will get the below output in Visual Studio looks
like.
The following example defines the SetText dependency property using for
TextBlock control, and shows the relationship of the DependencyProperty
identifier to the property that it backs.
The following example uses the SetText dependency property in XAML for
TextBlock control.
<local:TitleTextBlock
x:Name = "TitleTextBlock"
Text = "Hellow World"
Width="Auto" Height="25"
Grid.Column="0" Grid.Row="0" />
<Button
x:Name = "button" Height="25"
Content="Button" Click="button_Click"
Grid.Column="1" Grid.Row="0"
Margin="10,0,10,10"/>
</Grid>
To set text while press button you continue to create the button_Click method for
Button, and here is example looks like.
button_Click - C# Code
void button_Click (object sender, RoutedEventArgs e)
{
//Assign text to SetText property via Dependency Property
TitleTextBlock.SetText
= "Hellow DependencyProperty World";
}
Below is a screenshot of how call the SetText dependency property looks like.
Once you click Button control, you can see the “Hellow DependencyProperty
World” attached on the window as shown below.
3. Audio Content
To play the audio/video content based on the WAV format, you can use class
called SoundPlayer. SoundPlayer class use to control playback of a sound from a
.wav file.
Other the class for control playback of a sound is SoundPlayerAction. It uses to
pepresent a lightweight audio playback TriggerAction used to play .wav files.
Here is example shows SoundPlayerAction of using XAML code with our WPF
app.
<SoundPlayerAction x:Name="SoundPlayer2"/>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
Note: You can see full description of SoundPlayer class in project name is
WpfAppAudio and reference at https://docs.microsoft.com/en-
us/dotnet/api/system.media.soundplayer?view=netframework-4.8
Let's look at examples of how we can implement the C# code for this class.
Please make sure this audo files are selected Copy always in Copy to Output
Directory as follows.
Notice a few thing interesting in above example is the image for advertising display
on window.
Please enure this image file is selected Resource in Build Action as follows.
One you create the above examples, and run the program in Visual Studio you will
see the following output as follows.
1 2
By click Play Sound button or Rining Sound button, you can hear the sound of
Alex.Khang.wav and Kawai-K3-Violin-C6.wav.
4. Video Content
To represents a control that contains audio and/or video, you can use
MediaElement class.
When distributing media with your application, you cannot use a media file as a
project resource. In your project file, you must instead set the media type to
Content and set CopyToOutputDirectory to PreserveNewest or Always.
Note: You can see full description of MediaElement class in project name is
WpfAppVideo and reference at https://docs.microsoft.com/en-
us/dotnet/api/system.windows.controls.mediaelement?view=netframework-4.8
There are two different modes can be used for MediaElement, it dependent on
what is driving the control: independent mode or clock mode.
You might want to write code in Loaded event handler of window like this snippet.
Please make sure this video file is selected Copy always in Copy to Output
Directory as follows.
Here is scenario shows the playback of MP4 file by using MediaElement class.
By apply Drag and Drop feature, you can allow users to select any video or audo
file from Windows Explorer and drag into MediaElement and play instantly.
Notice that if you drop an audio file, you can listen the sound only, in this case
you can display Image control over MediaElement for doing some interesting such
as advertising.
Below XAML Code shows an example of Drop event handler and AllowDrop
property, when a file is dragged and dropped.
Here is an example shows how to write C# code in Drop event of window that
handles this action of behavior.
{
//pick file extention name from file name
string extensionName = System.IO.Path
.GetExtension (itemName);
//pick file name from file name
videoName = System.IO.Path
.GetFileNameWithoutExtension (itemName);
if (extensionName != "")
{
if (extensionName == ".wmv" ||
extensionName == ".mp3"||
extensionName == ".wav" ||
extensionName == ".avi" ||
extensionName == ".mp4")
{
if (path == "") path = itemName;
}
}
}
//Assign file name to Source property
xMediaPlayer.Source = new Uri
(path, UriKind.RelativeOrAbsolute);
this.Title = "Video Player - " + videoName;
//Call Play () method to play name
xMediaPlayer.Play();
}
}
To run app in above example, you select audio or video file from Windows
Explorer and drop on MediaElement below picture.
Notice that the code above will complite and work properly if you have
Wildlife.mp4 file in project looks like this.
5. Rich Media
Rich media is a digital advertising term for an ad that includes advanced features
like video, audio, or other elements that encourage watchers, learners or viewers
to interact and engage with the interesting content.
To create rich media desktop app, copying the previous XAML code, you could
cover the design of the primary layout on a continuing project as follows.
The design continues in this way for the whole period of creating the
WpfAppRichMedia project, you can see the final layout as follows.
3
4
To have above layout, let's perform the following steps to achieve this.
Step 1, you can devide an available Grid control to one column and 4 rows by
using ColumnDefinition and RowDefinition as follows.
</Grid.ColumnDefinitions>
</Grid>
Step 2, move MediaElement control to the first column and the first row by specify
Grid.Column="0" Grid.Row="0".
Here is XAML code of the MediaElement control and its properties as well as
event handlers.
Becasue of rich media is an advertising term for any desktop app or web app that
uses advanced technology such as streaming video or music that interact instantly
with the user, and banner or content that change when the user's playback or
mouse passes over it. So, continue next step.
Step 3, add the TextBlock control to the first column and the second row by
specify Grid.Column="0" Grid.Row="1".
Here is XAML code of the TextBlock control and its default content.
x:Name = "Subtitle"
HorizontalAlignment="Stretch" TextWrapping="Wrap"
Text="Here is Subtitle: Windows Presentation
Foundation (WPF) in Visual Studio provides
developers with a unified programming model for
building line-of-business desktop applications
on Windows."
Width="650" MinWidth="400" Height="40"
VerticalAlignment="Center"
Grid.Column="0" Grid.Row="1"
/>
Step 4, add a Grid control to the first column and the second row by specify
Grid.Column="0" Grid.Row="2" and then devides it to 3 columns and 1 row as
follows.
Add the first TextBlock control to the first column, Slider control to the second
column and the second TextBlock control to the third column, and here is an
example shows of the Slider and TextBlock controls along with their properties.
Custom track bar is combined with slider bar and text in the playback of streaming
media in order to show the current timeming position versus the playback position.
The position slider is horizontal and has a single handle that can be moved with
the mouse or by using the arrow keys. So, to handle the behavior of user when
they move forward or back on position slider, you can use DragStarted and
DragCompleted.
Here is example shows DragStarted event handler as follows.
To start the tracking process of media position, you can add the following C#
code snippet to the MediaOpened event handler as follows.
Related to a isDrag variable is used many times in above examples and how to start
the tracking process of media position, you must add the timer_Tick method as
follows.
The last row is contained buttons act as shuffer, replay, speaker, play, rewind,
forward and fullscreen.
Step 5, add a Grid control to the first column and the second row by specify
Grid.Column="0" Grid.Row="3" and then devides it to 8 columns and 1 row as
follows.
Step 5.1, add an Image control to the first column, here is an example shows of
the shuffer action as follows.
<Image
x:Name = "Shuffer"
HorizontalAlignment="Center"
Height="28" Width="28"
VerticalAlignment="Top"
Source="Resources/shuffer.png"
Grid.Row="0" Grid.Column="0"
/>
Step 5.2, the media app should have an Auto replay option, its just a trick you need
to pull of using the media playlist feature or continues the playback the current
video until you stop it.
Adding an Image control to the second column, here is an example shows of the
replay / repeat action as follows.
To enable Auto replay/repeat button for video player on your app or not, here is
an example shows how to write C# code that handles
PreviewMouseLeftButtonDown event of this action.
The above example is compiled successfully; you must add the GetBitmapImage
method as follows.
Step 5.3, add an Image control to the third column to control speaker status, here
is an example shows of the turn on/off action as follows.
To turn on / off Speaker, here is an example shows how C# code that handles
behavior of speaker based on loudspeaker_PreviewMouseLeftButtonDown event.
Speaker – C# Code
//Turn on or off the speaker option
bool hasSpeaker = true;
void loudSpeaker_PreviewMouseLeftButtonDown (object sender,
MouseButtonEventArgs e)
{
//Image for representing the turn-on status
string imagePath = "Resources/loudspeaker-on.png";
//Negative status of the speaker option
hasSpeaker = !hasSpeaker;
if (hasSpeaker)
{
//If status is turned-on, turn-off the speaker option and change image
xMediaPlayer.IsMuted=false;
imagePath = "Resources/loudspeaker-on.png";
loudSpeaker.ToolTip = "On";
Step 5.4, as a longtime media user, one of the changes I was most excited about
with sound bar was the design that the friendly experiences.
For this enclose project, add an Image control to the fourth column, here is an
example shows of the volume bar as follows.
ValueChanged="VolumnSlider_ValueChanged"
/>
To adjust the volume sound by C# code, here is an example shows how to handles
behavior of volume based on VolumnSlider _ValueChanged event handler.
Step 5.5, add an Image control to the fifth column, here is an example represents
the Move First action to start from the beginning as follows.
Familiar Move First, add an Image control to the seventh column, here is an
example represents the Move Last button to go to the end as follows.
<Image
x:Name="MoveLast"
HorizontalAlignment="Center"
Grid.Row="0" Grid.Column="4"
Height="28" Width="28"
VerticalAlignment="Top"
Source="Resources/last.png"
PreviewMouseLeftButtonDown=
"MoveLast_PreviewMouseLeftButtonDown"
/>
Step 5.6, add an Image control to the sixth column, here is an example represents
the Play/Pause action to play or stop media as follows.
VerticalAlignment="Top" HorizontalAlignment="Center"
PreviewMouseLeftButtonDown=
"imagePlay_PreviewMouseLeftButtonDown"
ToolTip="Start" Source="Resources/pause.png"
/>
{
// If media is playing status, change ToolTip property
// call Pause method and change image name
imagePath = "Resources/play.png";
imagePlay.ToolTip = "Play";
xMediaPlayer.Pause();
}
imagePlay.Source = GetBitmapImage (imagePath);
}
Final step, add an Image control to the eighth column, here is an example
represents the full screen action to maximize or minimize window as follows.
FullScreen – C# Code
void FullScreen_PreviewMouseLeftButtonDown (object sender,
MouseButtonEventArgs e)
{
if (this.WindowState == WindowState.Maximized)
{
this.WindowState = WindowState.Normal;
}
else
{
this.WindowState = WindowState.Maximized;
}
}
If the above steps are followed, run the WpfAppRichMedia project and you will
get media player as the below output.
If you want the audio/video that will automatically start playing as soon as it is
loaded, you must add Loaded event handler as follows.
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:WpfAppVideo"
mc:Ignorable="d"
Title="Video Player"
WindowState="Normal"
WindowStartupLocation="CenterScreen"
Height="530" Width="720"
MinHeight="500" MinWidth="680"
AllowDrop="True"
Drop="Window_Drop"
Loaded="Window_Loaded"
>
Here is example shows how to start playing the audio/video in Loaded event
handler.
Before you package your desktop app, you might have to do much to get your
application ready for the packaging process. Here is references some of the most
commonly used optional parameters for your app.
Note: The links below are provided for further information of build and package:
https://docs.microsoft.com/en-us/windows/uwp/porting/desktop-to-uwp-
prepare
Step 2, Right clicking on Project name and Project Properties window will open
then you can add icon for app, the settings screen will look like this.
Step 3, click Assembly Information button, you need to provide the properties for
getting the information about the application, such as the version number,
description, loaded assemblies, and so on. As shown here.
Step 4, open the Publish tab, you make sure that application files are included as
follows.
Step 6, provides information for section of Publish options and other information
are keeped in default, it will look like this.
If you click Publish Now button, Visual Studio will package your app by default
options. Once you've done it, you will get full package as the below output.
If you click Publish Wizard button, Visual Studio will package your app by manual
settings. The first option will look like this.
Click Next button, you have three options for store app package as follows.
How will users install the app? they are described as follows
From a Web site option: It is most choice when the publish location is a
FTP path, and it will allow user to install your app from Web site.
Notice that you have created the wpf folder on hosting before select this option.
If choose “From a Web site” or “From a UNC path or file share” option, you
will get an additional option as follows.
The first option allows user launch your app from a shortcut menu regardless of
whether the computer is online or offline. If machine is connected to the network
or internet, the app will check for new version in the location where it was
published. If an any update exists, it will prompt the user for deceide to install or
not.
In case of the second option, an app can not launch when the machine is not
connected to the network or internet.
Click Finish button and can see HTML file with guideline for installing your app
as follows.
Please aware the Windows Application Packaging Project appears only in Visual
Studio 2019 version 15.5 or higher.
Note: the links below are provided for further information of Windows
Application Packaging Project: https://docs.microsoft.com/en-
us/windows/uwp/porting/desktop-to-uwp-packaging-dot-net
However, if you want to have a complexity configuration for your package, please
take a look how to add Windows Application Packaging Project and name is
ERPSystemSetup as follows.
To package ERPSystem project, you must add a reference to the ERPSystem and
here is figure shows this mode.
Select Add Reference, you will get the list of projects in current solution shows on
the next window as follows.
You can include multiple WPF apps in this package, but only one of them can
start. So, right clicking on the app name that you want users to start when they
choose the app's name, and then choose Set as Entry Point.
Next, open Configuration Manager and ensure that your projects target the same
platform and release mode.
Then, right clicking on the setup project name and select Store -> Create App
Packages, the first window looks like.
Next, you can configure some options and click Create button as follows.
Once you complete the above steps, you will see package folder the following
output.
Dependent on your option while puhlish app, you can copy folders and files into
removeable disk or file share or ftp location.
Next, let’s see how to install this app is installed on the end user’s PC.
Step 1, double click the setup.exe file and it could be bringed up an error dialog
shown same picture as follows.
This error is caused by a user without sufficient privileges to write the file on the
directory or setup.exe file is produced by the “From a Web site” or “From a
UNC path or file share” options. It will look like this: Error: An error occurred
trying to download 'http://www.xokr.net/wpf/ERPSystem.application'.
If it launches smoothly and safely, you will get the next window as the following
output.
Click an Install button, the next window will show up and wait for your selection,
and here is picture looks like.
One you complete the above installation steps; you will see the shotcut menu on
Start Meny as the following output.
Combining the practical examples used in this section, you could now have a feel
for some powerful features and that is why the developers is realy like to use WPF
UI/UX.
Hopefully, the project built for this section was in formally introduced to you the
fastest and easiest way to create a WPF app that interacts with the database.
References
While writing this book, I have read and referenced to a few knowledge and
examples from website.
https://docs.microsoft.com/en-us/visualstudio/designers/introduction-
to-wpf?view=vs-2019
https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/
https://visualstudio.microsoft.com/
https://docs.microsoft.com/en-us/sql/sql-server/sql-server-technical-
documentation?view=sql-server-2017
https://docs.microsoft.com/en-us/sql/sql-server/sql-server-technical-
documentation?view=sql-server-ver15