65.9K
CodeProject is changing. Read more.
Home

Simple WPF Binding in Code-behind for Visual Basic .NET

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.75/5 (4 votes)

Nov 7, 2020

Public Domain

4 min read

viewsIcon

8348

downloadIcon

116

Updating user interface in WPF with simple one-way binding

Introduction

The UI management can be time consuming and a source of frustration, especially when our project is made up of several concurrent threads, each of which needs to update its own part of it.

At times, when data flows rapidly in and out of the project, the user needs to have a quick update of important variables. Whether they would be volatile stock market prices or water flow rate in a pipe, the faster the UI update of that property, the faster the reaction of the user to it.

When the same property is accessed from different parts of the project, updating the UI in real time becomes tedious and source of errors. We will see in this small project how to bind the property value to its representation on the UI.

There are multiple better and more in-depth examples on the Internet, although most of them deal with C#, and others are too convoluted to follow. The approach in this project is focused on simplicity and essentiality, for the benefit of inexperienced VB.NET developers.

Setting It Up

The purpose of this project is to validate the user input, parse whether the input is a Double, and if so, show it with two decimals, thousands separator and the currency symbol. If the user input is not a Double, visualise an error message. We want this to happen as the user types, and do not want to wait for him to enter or confirm the input.

Step by Step Walkthrough

We’ll start setting up by creating a new WPF .NET Framework, VB.NET project. In the default window, drag just one Textbox and one Textblock.

MainWindow.xaml would look more or less like this:

<Window x:Class="MainWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       mc:Ignorable="d" Title="MainWindow" Height="160" Width="380" ResizeMode="NoResize" >
    <Grid x:Name="myGrid" >
        <TextBlock x:Name="Output" HorizontalAlignment="Left" Margin="195,45,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="124" Height="23"/>
        <TextBox x:Name="Input" Text="0" HorizontalAlignment="Left" Height="23" Margin="40,45,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
    </Grid>
</Window>

We’ll come back to MainWindow.xaml later, when we will need to declare the Binding of the TextblockOutput” to the TextboxInput”. Close it for now and let’s dig into the code.

First thing, declare a public Property and its private representation.

Private m_InputText As String
Public Property InputText As String

We also need to declare a PropertyChanged event, that will fire when the property is changed. If multiple properties are present in the project, the same event can be reused, by passing the appropriate argument.

Public Event PropertyChanged As PropertyChangedEventHandler

The event associated with Input.Textchanged will look like this:

Private Sub Input_TextChanged(sender As Object, e As TextChangedEventArgs) _
        Handles Input.TextChanged
        InputText = Input.Text
End Sub

What we’re doing with that is just assign the string Input.Text to the Property InputText (which is also a String of course).

It’s time to modify the Property with our parsing and validation code, like this:

    Public Property InputText As String
        Get
            Return m_InputText
        End Get
        Set(value As String)
            Dim validResult As Double
            If Double.TryParse(value, validResult) Then
                m_InputText = validResult.ToString("C2")
            Else
                m_InputText = "Invalid amount"
            End If
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("InputText"))
        End Set
    End Property

Basically, what we are doing is trying to cast the String to a Double. If we succeed, the new value will be converted back to a String, formatted as a two-digit decimal currency value (“C2”) and assigned to m_InputText. If no casting is possible, the string will contain “Invalid Amount”.

Whether m_InputText contains a valid currency value or not, we raise a PropertyChanged event, by passing the appropriate Sender and Property that changed. As you see, by changing the PropertyChangedEventArgs appropriately, the same Event can be reused for different Properties.

We are already almost there. There are just a couple of more things to do for setting up the Binding.

The UI must be notified that a Property changed in the code behind, and we also need to tell the Binding what is the DataContext where to look for the Property that changed. Notifications are managed by the Interface INotifyPropertyChanged which resides in the Namespace System.ComponentModel. We need to import that Namespace, and declare the interface implementation. The binding DataContext, in our example, is the entire Instance of MainWindow (Me). There may times where we need to restrict the DataContext (e.g.: same property in different instances of a class), but this is beyond the scope of this article.

Imports System.ComponentModel
Class MainWindow
    Implements INotifyPropertyChanged
    Public Sub New()
        InitializeComponent()
        DataContext = Me
    End Sub
…

The event PropertyChanged must implement the interface to the UI, therefore its declaration becomes as follows:

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

Finally, it’s time to go back and edit the MainWindow.xaml to declare the Binding to our property, by modifying the declaration of TextBlockOutput”:

<TextBlock x:Name="Output" HorizontalAlignment="Left" Margin="195,45,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="124" Height="23" Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}" />

Run the program and you should see the following results.

Valid input:

Invalid input:

Conclusion and Points of Interest

In this article, we just scratched the very surface of the Binding world. By following the example provided, the user could later expand to a whole range of different and more complete implementations and possibilities. Bindings are a simpler way to update the UI, by avoiding the necessity of thread-safe calls and delegates.

The user is encouraged to experiment the two-way Binding, which is not discussed here.

It is also interesting to notice how simple and compact it is to code Binding in VB.NET, when compared to C#.

History

  • 6th November, 2020: Initial version