Archive for the ‘MVVM’ Category.

WPF NavigationService blanks PasswordBox.Password, which breaks the MVVM PasswordHelper

I am using three things that are just not friends:

  • Pages and NavigationService
  • Model-View-ViewModel design
  • The PasswordBox control

Problem 1 – PasswordBox.Password is not a DependencyProperty

First off, Model-View-ViewModel is design centered around data binding. But PasswordBox.Password is not a DependencyProperty and therefore does not support binding. That is ok, a PasswordBoxAssistant (alternately I have seen it named PasswordHelper or PasswordBoxHelper) as described originally here and also here fixes seems to fix this.

That is, it fixes it unless you are using the NavigationService.

Problem 2 – NavigationService blanks PasswordBox.Password

See when the NavigationService navigates to another page, it somehow know that the current page has a PasswordBox and if it finds a PasswordBox, it blanks the password out.  So since we are using PasswordBoxHelper to make MVVM and data binding work, the value is blanked in the ViewModel and Model as well.

For now, I happen to be using a custom button for navigation so I can simply do this in my ViewModel:

String tempPw = MyPassword;
NavigationService.Navigate(NewPage);
MyPassword = tempPw;

However, this is not the best solution. What if there were multiple links and different ways to navigate?

I think the best solution would be to figure out how to make PasswordBoxAssistant handle this. But I am not sure how or if there is anyway to tell that the password was blanked by the NavigationService and to ignore binding in this instance.

Resource:
http://social.msdn.microsoft.com/Forums/en/wpf/thread/d91aec90-1476-41c0-a925-7661745094c5

Navigation and Pages using Model-View-ViewModel (MVVM)

I am working on a project at work that is a navigation application.

I wanted to use MVVM. I also wanted to document for others how I designed this, as there wasn’t much online about using MVVM with Navigation and Pages.

Here is my project. I will post an explanation of this project as soon as I can get to it, so look for it.

Project Download – Small: Navigation-Pages-MVVM.zip

Project Download – More complete: Navigation-Pages-MVVM 2.0

Binding Visibility to a bool value in WPF

I was putting code in my ViewModel that returns Visibility but I didn’t really like that very much. If the UI is created with something other than WPF, that is really not going to work. Since I intend to do cross compile my code in Mono, which doesn’t have WPF but uses either Forms or GTK#, I have already encountered this issue. What I really want to use is bool.

The solution is IValueConverter. If you just want the code and don’t want to read this post, just scroll to the bottom and grab the

IValueConverter is part of PresentationFramework (in PresentationFramework.dll) so it isn’t available in Mono, but that is OK because you don’t instantiate it in the ViewModel, you use it in the View so it will only be used when the GUI is part of WPF. So if you are separating your View into a separate DLL, this would be included in the View DLL, that way when you compile everything else, with say a different GUI that uses GTK#, you won’t get a compiler error because PresentationFramework doesn’t exist in Mono.

BooleanToVisibilityConverter

Well, there is an object already created for you called BooleanToVisibilityConverter, but it is limited. True is converted Visibility.Visible. False is converted to Visibility.Collapsed.

Here we see a problem. Visibility has three possible values but a Boolean only has two.

Boolean Visibility
True Visible
False Collapsed
Hidden

This will cover many of the scenarios, but not all.

Here is how it would be used.

For this example, I have this Person class.

    public class Person
    {
        public Person() { }
        public String FirstName { get; set; }
        public String LastName { get; set; }
        public String Age { get; set; }
    }

Here is a simple View for this object. It has a Grid that has a Label and TextBox for each property in the Person object. It also has a CheckBox. The CheckBox gives us a easy bool value, IsChecked. This works similar to a bool property in a ViewModel.

<Window x:Class="TestBooleanToVisibilityConverter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TestBooleanToVisibilityConverter"
        Title="MainWindow"
        SizeToContent="WidthAndHeight"
        >
    <Grid Margin="20">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid Name="PersonViewGrid">
            <Grid.Resources>
                <BooleanToVisibilityConverter x:Key="BoolToVisConverter"/>
            </Grid.Resources>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Label Content="First Name:" Grid.Column="0" Grid.Row="0" />
            <TextBox Grid.Column="1" Grid.Row="0" Name="firstNameTextBox"
                     Text="{Binding Path=FirstName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" MinWidth="175" />
            <Label Content="Last Name:" Grid.Column="0" Grid.Row="1" />
            <TextBox Grid.Column="1" Grid.Row="1" Name="lastNameTextBox"
                     Text="{Binding Path=LastName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" MinWidth="175" />
            <Label Content="Age:" Grid.Column="0" Grid.Row="2"
                   Visibility="{Binding IsChecked, ElementName=ShowAgeCheckBox, Converter={StaticResource BoolToVisConverter}}"/>
            <TextBox Grid.Column="1" Grid.Row="2" Name="ageTextBox"
                     Text="{Binding Path=Age, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" MinWidth="175"
                   Visibility="{Binding IsChecked, ElementName=ShowAgeCheckBox, Converter={StaticResource BoolToVisConverter}}"/>
        </Grid>
        <Grid Grid.Row="1">
            <CheckBox Name="ShowAgeCheckBox" Content="Show Age" />
        </Grid>
    </Grid>
</Window>

I am not using MVVM for this example, but instead there is a just a single object created in the code behind for demo purposes.

using System;
using System.Windows;

namespace TestBooleanToVisibilityConverter
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent(); Person p = new Person() { FirstName = "Michael", LastName = "Michaels", Age = "33" };
            PersonViewGrid.DataContext = p;
        }

    }
}

Ok, now build the project and you will see that the Label and TextBox for Age are hidden until you check the box.

Writing your own Bool to Visibility Converter

Sometimes you may need to write you own Converter.  For example, in the above project, it is annoying how the CheckBox moves up and down in position because Visibility.Collapsed is used instead of Visibility.Hidden.  You may want to use Visibility.Hidden instead.

You can write your own Converter that returns Visibility.Hidden instead of Visibility.Collapsed.

BooleanToVisibleOrHidden.cs

using System;
using System.Windows.Data;
using System.Windows;

namespace TestBooleanToVisibilityConverter
{
    class BoolToVisibleOrHidden : IValueConverter
    {
        #region Constructors
        /// <summary>
        /// The default constructor
        /// </summary>
        public BoolToVisibleOrHidden() { }
        #endregion

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool bValue = (bool)value;
            if (bValue)
                return Visibility.Visible;
            else
                return Visibility.Hidden;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Visibility visibility = (Visibility)value;

            if (visibility == Visibility.Visible)
                return true;
            else
                return false;
        }
        #endregion
    }
}

Here we do the conversion ourselves and now we have a different conversion table.

Boolean Visibility
True Visible
Collapsed
False Hidden

Now replace the Converter object in your XAML.  We only change Line 15.

      <local:BoolToVisibleOrHidden x:Key="BoolToVisConverter"/>

This works, but it could be improved. This still leaves us having to choose between two objects.

Creating a Converter that supports a choice of Hidden or Collapsed.

Here we will provide a property that determines if we should collapse or not.

Add a property called Collapse and return the appropriate Visibility based on that property. Here is the new object. As you see, the code changes to add this feature is really just an empty bool property and an if statement that used the bool property.

using System;
using System.Windows.Data;
using System.Windows;

namespace TestBooleanToVisibilityConverter
{
    class BoolToVisibleOrHidden : IValueConverter
    {
        #region Constructors
        /// <summary>
        /// The default constructor
        /// </summary>
        public BoolToVisibleOrHidden() { }
        #endregion

        #region Properties
        public bool Collapse { get; set; }
        #endregion

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool bValue = (bool)value;
            if (bValue)
            {
                return Visibility.Visible;
            }
            else
            {
                if (Collapse)
                    return Visibility.Collapsed;
                else
                    return Visibility.Hidden;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Visibility visibility = (Visibility)value;

            if (visibility == Visibility.Visible)
                return true;
            else
                return false;
        }
        #endregion
    }
}

Now in your XAML you have the option to do nothing, which uses the bool default value false, or to set the Collapse property to true as shown below.

      <local:BoolToVisibleOrHidden x:Key="BoolToVisConverter" Collapse="True"/>

We now support either feature with the following table. We probably at this point would rename the object to BooleanToVisibilityConverter, but Microsoft already took that object name so I will leave it named as is.

Boolean Visibility
True Visible
False – Collapse=True Collapsed
False – Collapse=False Hidden

We are starting to get a little more usability from one object.

Adding the Reverse feature so False is Visible and True is Collapsed or Hidden

Lets say we want to change the CheckBox so that instead of saying “Show Age” it says “Hide Age”.

            <CheckBox Name="ShowAgeCheckBox" Content="Hide Age" />

Now we have to reverse the mapping. If Reverse=”True” we want the mapping to be like this:

Boolean Visibility
False Visible
True – Collapse=True Collapsed
True – Collapse=False Hidden

This is also quite simple. We add another bool property called Reverse. Then key of that in another if statement.

using System;
using System.Windows.Data;
using System.Windows;

namespace TestBooleanToVisibilityConverter
{
    class BoolToVisibleOrHidden : IValueConverter
    {
        #region Constructors
        /// <summary>
        /// The default constructor
        /// </summary>
        public BoolToVisibleOrHidden() { }
        #endregion

        #region Properties
        public bool Collapse { get; set; }
        public bool Reverse { get; set; }
        #endregion

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool bValue = (bool)value;

                if (bValue != Reverse)
                {
                    return Visibility.Visible;
                }
                else
                {
                    if (Collapse)
                        return Visibility.Collapsed;
                    else
                        return Visibility.Hidden;
                }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Visibility visibility = (Visibility)value;

                if (visibility == Visibility.Visible)
                    return !Reverse;
                else
                    return Reverse;
        }
        #endregion
    }
}

Now you can reverse this very easily in the XAML.

      <local:BoolToVisibleOrHidden x:Key="BoolToVisConverter" Collapse="True" Reverse="True" />

And now you have a much more full featured converter.

Additional Thoughts

I have to wonder why the developers didn’t do this originally with the BooleanToVisibilityConverter object. It is so simple. This is a perfect example of where Microsoft would benefit from Open Sourcing some of their code. A dozen people would have contributed this change by now if they had and all Microsoft would have to do is look at the submitted code, approve, and check it in.

www.wpftutorial.net – just found a new WPF Tutorial site

I just found http://www.wpftutorial.net.

Just another resource for WPF information.

A Hello World template of a WPF application using MVVM

Hey all,

I created an MVVM project and then saved it as a template.  This way when I create new projects, I can simple choose MVVM Base and save a ton of time.

You can use my template if you want.  You can download it here: MVVM Base.zip

How to add the MVVM Base template to your Visual Studio

If you want this to be available as a new project type in you Visual Studio install, follow these steps.

  1. go to this path under My Documents:Visual Studio 2010\My Exported Templates
  2. Download this template to that directory. MVVM Base.zip
  3. Create a new Visual Studio Project and choose MVVM Base from the list of C# projects.

A Progress Bar using WPF's Progress Bar Control, BackgroundWorker, and MVVM

Hey all,

WPF provides a ProgressBar control.  But there isn’t really a manual for it, especially if you want to follow MVVM.

So I am going to make a little application that counts from zero to ten and tracks the progress.  You are going to see when it is OK to use the foreground and when it is not OK but better to use BackgroundWorker.

While much of this code may be production ready, you should be aware that this code intentionally implements a foreground process that is an example of what not to do.

Prerequisites

  • Visual Studio

Step 1 – Create a new WPF Application Project

  1. In Visual Studio, create a new Solution and choose WPF Application
  2. Give it a name.
  3. Hit OK.

Step 2 – Add two base MVVM files

There are two basic classes used for MVVM.

  • RelayCommand
  • ViewModelBase

These are found on different blogs and different posts all over the internet, so I would say they are public domain, or free and unlicensed.

  1. Download them zipped here. MVVM
  2. Extract the zip file.
  3. Add the MVVM folder and the two class under it to your project.

Step 3 – Create a ProgressBarViewModel class

  1. Create a new Class called ProgressBarViewModel.
  2. Adding a using MVVM statement at the top.
  3. Make the class inherit ViewModelBase.
    class ProgressBarViewModel : ViewModelBase
    {
    }
    

This will be populated as we create our View.

Step 4 – Design the GUI in MainWindow.xaml

Ok, so lets create the GUI.

  1. Add a local reference. (Line 4)
  2. Add a ProgressBarViewModel object as a resource. (Lines 6-8)
  3. Create a StackPanel in the default Grid to put everything in. (Line 10)
  4. Add a one character label in great big text to display our number. (Line 11)
  5. Add a ProgressBar element. (Line 12)
  6. Create buttons to manipulate the label. (Lines 13-16)
  7. Configure the DataContext of each element to be the the ProgressBarViewModel using the Key PBVM we gave it when we added it as a resource. (Lines 11-16)
  8. Think of and create Binding Paths for each element. Yes, we can basically just make these Path names up and add them to the ProgressBarViewModel later. (Lines 11-16)

Here is the XAML.

<Window x:Class="WPFProgressBarUsingBackgroundWorker.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WPFProgressBarUsingBackgroundWorker"
        Title="MainWindow" >
    <Window.Resources>
        <local:ProgressBarViewModel x:Key="PBVM" />
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Label Content="{Binding Path=Value}" DataContext="{StaticResource ResourceKey=PBVM}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Name="labelNumberCounter" VerticalAlignment="Center" FontSize="175" />
            <ProgressBar Margin="0,3,0,3" Height="20" Name="progressBar" Value="{Binding Path=Value}" DataContext="{StaticResource ResourceKey=PBVM}" Minimum="{Binding Min}" Maximum="{Binding Max}"/>
            <Button Command="{Binding Path=IncrementBy1}" Content="Manual Count" DataContext="{StaticResource PBVM}" Height="23" IsEnabled="{Binding Path=IsNotInProgress}" Name="button1" Width="Auto" />
            <Button Margin="0,3,0,3" IsEnabled="{Binding Path=IsNotInProgress}" Command="{Binding Path=IncrementAsForegroundProcess}" DataContext="{StaticResource ResourceKey=PBVM}" Content="Count to 10 as a foreground process" HorizontalAlignment="Stretch" Height="23" Name="buttonForeground" VerticalAlignment="Top" Width="Auto" />
            <Button Margin="0,3,0,3" IsEnabled="{Binding Path=IsNotInProgress}" Command="{Binding Path=IncrementAsBackgroundProcess}" DataContext="{StaticResource ResourceKey=PBVM}" Content="Count to 10 as a background process" HorizontalAlignment="Stretch" Height="23" Name="buttonBackground" VerticalAlignment="Top" Width="Auto" />
            <Button Command="{Binding Path=ResetCounter}" Content="Reset" DataContext="{StaticResource PBVM}" Height="23" IsEnabled="{Binding Path=IsNotInProgress}" Name="buttonReset" Width="Auto" />
        </StackPanel>
    </Grid>
</Window>

Step 5 – Populate the ProgressBarViewModel

  1. Create the following member fields.
    • Double _Value;
    • bool _IsInProgress;
    • int _Min = 0;
    • int _Max = 10;
  2. Create a matching property for each member field. Make sure that in the set function of the property you call NotifyPropertyChanged(“PropertyName”).
  3. Create a function for each of the four buttons and populate these functions with the code. See the functions in the code below:
    • Increment()
    • IncrementProgressForeground()
    • IncrementProgressBackgroundWorker()
    • Reset()
  4. Create and populate the functions for the BackgroundWorker.
    • worker_DoWork
    • worker_RunWorkerCompleted()
  5. Create the following RelayCommand instances as member Fields.
    • RelayCommand _Increment;
    • RelayCommand _IncrementBy1;
    • RelayCommand _IncrementAsBackgroundProcess;
    • RelayCommand _ResetCounter;
  6. Create matching ICommand properties for each RelayCommand, instantiating the RelayCommand with the correct function.

Here is the code for the ProgressBarViewModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Text;
using System.Windows.Input;
using MVVM;

namespace WPFProgressBarUsingBackgroundWorker
{
    class ProgressBarViewModel : ViewModelBase
    {
        #region Member Fields
        Double _Value;
        bool _IsInProgress;
        int _Min = 0, _Max = 10;
        #endregion

        #region Member RelayCommands that implement ICommand
        RelayCommand _Increment;
        RelayCommand _IncrementBy1;
        RelayCommand _IncrementAsBackgroundProcess;
        RelayCommand _ResetCounter;
        #endregion

        #region Constructors
        /// <summary>
        /// The default constructor
        /// </summary>
        public ProgressBarViewModel()
        {
        }
        #endregion

        #region Properties
        /// <summary>
        /// Used to mark if the counter is in progress so the counter can't be started
        /// while it is already running.
        /// </summary>
        public bool IsInProgress
        {
            get { return _IsInProgress; }
            set
            {
                _IsInProgress = value;
                NotifyPropertyChanged("IsInProgress");
                NotifyPropertyChanged("IsNotInProgress");
            }
        }

        public bool IsNotInProgress
        {
            get { return !IsInProgress; }
        }

        public int Max
        {
            get { return _Max; }
            set { _Max = value; NotifyPropertyChanged("Max"); }
        }

        public int Min
        {
            get { return _Min; }
            set { _Min = value; NotifyPropertyChanged("Min"); }
        }

        /// <summary>
        /// This is the Value.  The Counter should display this.
        /// </summary>
        public Double Value
        {
            get { return _Value; }
            set
            {
                if (value <= _Max)
                {
                    if (value >= _Min) { _Value = value; }
                    else { _Value = _Min; }
                }
                else { _Value = _Max; }
                NotifyPropertyChanged("Value");
            }
        }

        #region ICommand Properties
        /// <summary>
        /// An ICommand representation of the Increment() function.
        /// </summary>
        public ICommand IncrementBy1
        {
            get
            {
                if (_IncrementBy1 == null)
                {
                    _IncrementBy1 = new RelayCommand(param => this.Increment());
                }
                return _IncrementBy1;
            }
        }

        /// <summary>
        /// An ICommand representation of the IncrementProgressForegroundWorker() function.
        /// </summary>
        public ICommand IncrementAsForegroundProcess
        {
            get
            {
                if (_Increment == null)
                {
                    _Increment = new RelayCommand(param => this.IncrementProgressForeground());
                }
                return _Increment;
            }
        }

        /// <summary>
        /// An ICommand representation of the IncrementProgressForeground() function.
        /// </summary>
        public ICommand IncrementAsBackgroundProcess
        {
            get
            {
                if (_IncrementAsBackgroundProcess == null)
                {
                    _IncrementAsBackgroundProcess = new RelayCommand(param => this.IncrementProgressBackgroundWorker());
                }
                return _IncrementAsBackgroundProcess;
            }
        }

        /// <summary>
        /// An ICommand representation of the Reset() function.
        /// </summary>
        public ICommand ResetCounter
        {
            get
            {
                if (_ResetCounter == null)
                {
                    _ResetCounter = new RelayCommand(param => this.Reset());
                }
                return _ResetCounter;
            }
        }
        #endregion ICommand Properties
        #endregion

        #region Functions
        /// <summary>
        /// This function manually increments the counter by 1 in the foreground.
        /// Because it only increments by one, the WPF control bound to Value will
        /// display the new value when this function completes.
        /// </summary>
        public void Increment()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;

            // If the value is already at 10, start the counting over.
            if (Value == 10)
                Reset();
            Value++;
        }

        /// <summary>
        /// This function starts the counter as a foreground process.
        /// This doesn't work.  It counts to 10 but the UI is not updated
        /// until the function completes.  This is especially problematic
        /// since the buttons are left enabled.
        /// </summary>
        public void IncrementProgressForeground()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;
            Reset();
            IsInProgress = true;
            Value = 0;
            for (int i = _Min; i < _Max; i++)
            {
                Value++;
                Thread.Sleep(1000);
            }
            IsInProgress = false;
        }

        /// <summary>
        /// This starts the counter as a background process.
        /// </summary>
        public void IncrementProgressBackgroundWorker()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;

            Reset();
            IsInProgress = true;
            BackgroundWorker worker = new BackgroundWorker();
            // Configure the function that will run when started
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);

            /*The progress reporting is not needed with this implementation and is therefore
            commented out.  However, in your more complex application, you may have a use for
            for this.

            //Enable progress and configure the progress function
            worker.WorkerReportsProgress = true;
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);

            */

            // Configure the function to run when completed
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

            // Launch the worker
            worker.RunWorkerAsync();
        }

        /// <summary>
        /// This is the function that is called when the worker is launched with the RunWorkerAsync() call.
        /// </summary>
        /// <param name="sender">The worker as Object, but it can be cast to a worker.</param>
        /// <param name="e">The DoWorkEventArgs object.</param>
        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = _Min; i < _Max; i++)
            {
                Value++;
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// This worker_ProgressChanged function is not in use for this project. Thanks to INotifyPropertyChanged, this is
        /// completely unnecessary.
        /// </summary>
        /// <param name="sender">The worker as Object, but it can be cast to a worker.</param>
        /// <param name="e">The ProgressChangedEventArgs object.</param>
        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Does nothing yet
            throw new NotImplementedException();
        }

        /// <summary>
        /// This worker_RunWorkerCompleted is called when the worker is finished.
        /// </summary>
        /// <param name="sender">The worker as Object, but it can be cast to a worker.</param>
        /// <param name="e">The RunWorkerCompletedEventArgs object.</param>
        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            IsInProgress = false;
        }

        /// <summary>
        /// This function resets the Value of the counter to 0.
        /// </summary>
        private void Reset()
        {
            Value = Min;
        }
        #endregion
    }
}

I’m sorry that this is not the most Newbie proof post. But I tried to comment like crazy the code so you can get through it.

Now if you find a discrepancy in my walk-through, please comment. Also, if it is easier for you to just download the project, here it is:
WPFProgressBarUsingBackgroundWorker.zip