In the previous lesson, Code-Behind in C# .NET WPF and finishing the calculator, we finished making a simple calculator
application in C# .NET. In the next couple of lessons, we're going to create an
application I deem to be at a more intermediate level. It will remind the user
of his/her friends' birthdays. The end result will look like this:

The application is made up of two forms, which we will use to work with dates
and store data into files. Also, we are going to incorporate the Model-ViewModel
architecture, exceptions, and bindings. This lesson will go over a lot of new
information, but don't worry, we'll go step by step. I believe that practical,
relatively simple examples are the best way to go when learning to code. I'm
sure you'll make it through unscathed.

Form design

We'll start with the design, as always. Create a new WPF project and name it
BirthdayReminder.

The main form

Set the window title, its starting position (on the screen), and an icon.

Layout

There are several ways to achieve the desired form layout. One way would be
to split the Grid as follows:

The grid would have 4 rows and 2 columns. Rows heights are 20, 30, * and 30
DIP. The second to last one stretches along with the window. The left column has
a width of *, the right one has a fixed width of 200 DIP. The overall Margin is
set to 10 DIP. Once you have set all of the above, your Grid code will look like
this:

Upper TextBlocks

In the first two rows of the Grid, we set up a couple of TextBlocks with
information about today's date and the nearest upcoming birthday. The text
consists of several parts. We could potentially use a single TextBlock in each
row and concatenate its text value, but to keep it simple, we'll add several
TextBlocks next to each other.

StackPanel

When laying controls next to each other, vertically or horizontally, we use
StackPanels. A StackPanel is used to store controls, kind of
like the Grid. Add a StackPanel into each row in the grid. We not only want the
StackPanel to be in the first column but in the entire row. Which is why we add
the ColumnSpan attribute with a value of 2 (which stretches it over two
columns). It works sort of like colspan in HTML or merging table cells in Excel.
Also, there is such a thing as a RowSpan which stretches the element over
several rows. We'll set the Orientation attribute of the StackPanels to
Horizontal (the default value is Vertical). As well as add individual TextBlocks
straight into them (leave the data display TextBlocks empty).

Bottom buttons

Next, add two buttons to the last window row in the exact same way. Once
again, they will be in a StackPanel and stretch over two columns because we want
them next to each other. The StackPanel will be centered. We will have to assign
names to the buttons, in this case, because we will use them in the code-behind,
later on. Also, you will have to set the left button's right Margin to 10 in
order to keep them from being too close together.

Go ahead and run the application. Make sure to resize the window to make sure
that everything is responsive.

ListBox

All of the stored people instances will appear in a ListBox control. As the
name of the control suggests, it is a visual representation of an item list. As
a matter of fact, ListBoxes are an upgraded version of the ComboBox control.
Therefore, we work with them in the same way. In our case, we won't need to
define the items in XAML. However, we will load them later in the logical layer
of the application. Add a ListBox to the first column's third row, Name it
personsListBox and set its bottom Margin to 10 DIP.

Calendar

The last couple of things we will add to this form is a calendar and a few
TextBlocks above it. We could either create another Grid in its designated cell
or use a StackPanel (which we could use to line up our controls
horizontally/ver­tically). We'll go with the StackPanel because it is a bit
more flexible. Start by setting it's Left Margin to 10 DIP. Then, add 2
TextBlocks side by side to each row, which will be in separate StackPanels.
Calendars are declared as conveniently pre-made Calendar controls, which are
mainly used to choose a date and display it (which is basically what we need it
for).

Add-person dialog

Add a new window to the project, right-click on the project in the Solution
Explorer -> Add -> Window, and name it PersonWindow. Again, set the title,
the starting position, and the icon.

Let's take another look at the final result (the new window you just created
will be for the form on the right):

Layout

Now, split the Grid into 4 rows and 2 columns. Row heights will be as
follows: 4*, 30, 30, *. The first and the last row stretch along with the
window. Also, notice how the first one occupies 4 times more space than the last
one. Both columns will have a width of *, which is the default value, so just
leave that part as is. Next, set the Margin around the whole Grid to 10. Once
you have done all of this, the form will look like the following:

Image

Let's add an image, as well, so you could get some more experience working
with them. There are lots of icons available for download at http://www.iconfinder.com. Make sure you
read what kind of license the icon is under before you use it commercially. Once
you have downloaded an image, add it to the form using an Image control. Before
you do so, you will have to add it to the project in the same way you did with
the icon (dragging it to the Solution Explorer). Once you have added the image
to your project, set the name of the file to the Source attribute of an Image
control.

When you have a project in which you plan to use lots of images, make sure
you create a folder exclusively for them. Images stretch to fill the parent
control by default, which is not something we want. All you have to do to make
it keep its original proportions is set the Stretch attribute in the Image
control to "None". Last, of all, add the image to the entire Grid row using
ColumnSpan.

Label

We also need to add controls for entering names and birthdays in the next two
rows (on the second column). Start by placing a label for each control into the
first column. TextBlocks wouldn't don't suit our needs in this case, which is
why we will use labels. Labels text blocks that are bound to a particular
control. They also allow us to set keyboard shortcuts by placing an underscore
before a letter in its text. Then when you press ALT + the letter you wrote, the
control to which the label belongs will gain focus. To write an actual
underscore, one that doesn't set keyboard shortcuts, just write two of them.

A TextBox will do for entering names. As for the birthday, we'll use a
DatePicker control. Let's take a peek at how that would look:

We can see that the connection between the Label and the control is done by
the Target attribute. Also, notice the expression in the curly brackets that
starts with the word "Binding". Which literally binds things to one another, in
this case, a Label to a control of a given name. We'll run into binding pretty
often, so make sure you remember what it does! The rest of the code is nothing
new. Another thing we still have to add is to make the form visible at runtime.
We will get to that in the next lesson as well as make it so when you press ALT
+ J, the focus will be set to a name field. Whereas, ALT + D will set the focus
on the DatePicker.

Let's finish the dialog off by adding in the confirmation button, which will
appear in the middle of the last row.

We can set what the "default" and "cancel" keys do in every WPF window. The
enter key is the default key and triggers the OK button when pressed, whereas
the escape key triggers the cancel button. Now that that's been said, let's add
the IsDefault attribute to the button:

IsDefault="True"

If we wanted to close the dialogue by pressing Escape, all we would have to
do is add a Close button and set the IsCancel attribute to True to it.

Well, that's it for today! I think you've done plenty of form designing in
XAML for one day. Hopefully, you learned some new useful techniques as well. In
the next lesson, Birthday reminder in C# .NET WPF - Logic layer, we'll start working on the logical layer of the
application as well as the C# code. If needed, the form we designed today is
available for download below.

Download

The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.

The author learned IT at the Unicorn College - a prestigious college providing education on IT and economics.

Please, use the English language when posting at ICT.social. About your
question, you need to order items in your data source by birth date and set a
timer (look for DispatcherTimer) which will check whether there is an upcoming
birthday to remind. Your reminder can use the tray notification, look for
NotifyIcon.