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
(IsInProgress)
return
;
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
(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
(IsInProgress)
return
;
Reset();
IsInProgress =
true
;
BackgroundWorker worker =
new
BackgroundWorker();
worker.DoWork +=
new
DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted +=
new
RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
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)
{
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
}
}