Posted by: Zeeshan Amjad | January 23, 2010

Calculate Depreciation using MVVM Pattern


We have already discussed one example of MVVM pattern here and here. In that example there is only one class for data. In other words our model contain only one class. This time we are going to make our model with more than one class. This time our model class contains one class to store input variable and other class to store list to display the value of deprecation. Here is our classes for model.

  1: public class DepreciationInput : DependencyObject
  2: {
  3:     public static readonly DependencyProperty FixedAssetsProperty =
  4:         DependencyProperty.Register("FixedAssets", typeof(double), typeof(DepreciationInput));
  5: 
  6:     public static readonly DependencyProperty LifeSpanProperty =
  7:         DependencyProperty.Register("LifeSpan", typeof(int), typeof(DepreciationInput));
  8: 
  9:     public static readonly DependencyProperty ScrapValueProperty =
 10:         DependencyProperty.Register("ScrapValue", typeof(double), typeof(DepreciationInput));
 11: 
 12:     public double FixedAssets
 13:     {
 14:         get { return (double)GetValue(FixedAssetsProperty); }
 15:         set { SetValue(FixedAssetsProperty, value); }
 16:     }
 17: 
 18:     public int LifeSpan
 19:     {
 20:         get { return (int)GetValue(LifeSpanProperty); }
 21:         set { SetValue(LifeSpanProperty, value); }
 22:     }
 23: 
 24:     public double ScrapValue
 25:     {
 26:         get { return (double)GetValue(ScrapValueProperty); }
 27:         set { SetValue(ScrapValueProperty, value); }
 28:     }
 29: }
 30: 

Here is our class to store the list of our output the depreciated value.

  1: public class DepreciationInfo
  2: {
  3:     public int Year
  4:     { get; set; }
  5: 
  6:     public double Depreciation
  7:     { get; set; }
  8: 
  9:     public double AccDepreciation
 10:     { get; set; }
 11: 
 12:     public double BookValue
 13:     { get; set; }
 14: 
 15:     public double Percentage
 16:     { get; set; }
 17: }
 18: 
 19: public class DepreciationList : ObservableCollection<DepreciationInfo>
 20: {
 21: }
 22: 

Same as our previous program, we are going to make one utility class to implement the ICommand interface. Here is our utility class.

  1: public class MyCommand : ICommand
  2: {
  3:     public Func<bool> Function
  4:     { get; set; }
  5: 
  6:     public MyCommand()
  7:     {
  8:     }
  9: 
 10:     public MyCommand(Func<bool> function)
 11:     {
 12:         Function = function;
 13:     }
 14: 
 15:     public bool CanExecute(object parameter)
 16:     {
 17:         if (Function != null)
 18:         {
 19:             return true;
 20:         }
 21: 
 22:         return false;
 23:     }
 24: 
 25:     public void Execute(object parameter)
 26:     {
 27:         if (Function != null)
 28:         {
 29:             Function();
 30:         }
 31:     }
 32: 
 33:     public event EventHandler CanExecuteChanged
 34:     {
 35:         add { CommandManager.RequerySuggested += value; }
 36:         remove { CommandManager.RequerySuggested -= value; }
 37:     }
 38: }
 39: 

Here is complete XAML code of our program.

  1: <Window x:Class="Depreciation.Window1"
  2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4:     Title="Depreciation" Height="400" Width="600">
  5:     
  6:     <Grid Background="AliceBlue">
  7:         <Grid.RowDefinitions>
  8:             <RowDefinition/>
  9:             <RowDefinition/>
 10:             <RowDefinition/>
 11:             <RowDefinition Height="4*"/>
 12:             <RowDefinition/>
 13:         </Grid.RowDefinitions>
 14: 
 15:         <Grid.ColumnDefinitions>
 16:             <ColumnDefinition/>
 17:             <ColumnDefinition/>
 18:         </Grid.ColumnDefinitions>
 19:         <TextBlock Grid.Column="0" Grid.Row="0" Margin="5" VerticalAlignment="Center">Enter Cost of Fixed Asset</TextBlock>
 20:         <TextBox Grid.Column="1" Grid.Row="0" Margin="5" VerticalAlignment="Center" 
 21:                  Text="{Binding Path=DepreciationInput.FixedAssets}"/>
 22:         <TextBlock Grid.Column="0" Grid.Row="1" Margin="5" VerticalAlignment="Center">Enter life Span</TextBlock>
 23:         <TextBox Grid.Column="1" Grid.Row="1" Margin="5" VerticalAlignment="Center" 
 24:                  Text="{Binding Path=DepreciationInput.LifeSpan}"/>
 25:         <TextBlock Grid.Column="0" Grid.Row="2" Margin="5" VerticalAlignment="Center">Enter Scrap Value</TextBlock>
 26:         <TextBox Grid.Column="1" Grid.Row="2" Margin="5" VerticalAlignment="Center" 
 27:                  Text="{Binding Path=DepreciationInput.ScrapValue}"/>
 28: 
 29:         <ListView Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" 
 30:                   Margin="5" HorizontalContentAlignment="Stretch"
 31:                   ItemsSource="{Binding Path=DepreciationList}">
 32:             <ListView.View>
 33:                 <GridView>
 34:                     <GridView.ColumnHeaderTemplate>
 35:                         <DataTemplate>
 36:                             <Border BorderBrush="Brown" BorderThickness="2" CornerRadius="5">
 37:                                 <Border.Background>
 38:                                     <LinearGradientBrush>
 39:                                         <GradientStop Offset="0" Color="Wheat"/>
 40:                                         <GradientStop Offset="1" Color="LightCoral"/>
 41:                                     </LinearGradientBrush>
 42:                                 </Border.Background>
 43:                                 <TextBlock Foreground="Blue" FontSize="14" FontWeight="Bold" Margin="5" Text="{Binding}" Width="Auto"/>
 44:                             </Border>
 45:                         </DataTemplate>
 46:                     </GridView.ColumnHeaderTemplate>
 47:                     <GridViewColumn Width="Auto" Header="Year" DisplayMemberBinding="{Binding Path=Year}"/>
 48:                     <GridViewColumn Width="Auto" Header="Depreciation" DisplayMemberBinding="{Binding Path=Depreciation}"/>
 49:                     <GridViewColumn Width="Auto" Header="Accumulated Depreciation" DisplayMemberBinding="{Binding Path=AccDepreciation}"/>
 50:                     <GridViewColumn Width="Auto" Header="Book Value" DisplayMemberBinding="{Binding Path=BookValue}"/>
 51:                     <GridViewColumn Width="Auto" Header="Percentage">
 52:                         <GridViewColumn.CellTemplate>
 53:                             <DataTemplate>
 54:                                 <ProgressBar Width="50" Height="20" Margin="5" Minimum="0" Maximum="100" Value="{Binding Percentage}"/>
 55:                             </DataTemplate>
 56:                         </GridViewColumn.CellTemplate>
 57:                     </GridViewColumn>
 58:                 </GridView>
 59:             </ListView.View>
 60:         </ListView>
 61:         <Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="4" Margin="10" Width="75"
 62:                 Content="Calculate" Command="{Binding CalculateDepreciationCommand}"/>
 63:     </Grid>
 64: </Window>
 65: 

And here is complete C# code of our program.

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.Windows;
  6: using System.Windows.Controls;
  7: using System.Windows.Data;
  8: using System.Windows.Documents;
  9: using System.Windows.Input;
 10: using System.Windows.Media;
 11: using System.Windows.Media.Imaging;
 12: using System.Windows.Navigation;
 13: using System.Windows.Shapes;
 14: using System.Collections.ObjectModel;
 15: using System.ComponentModel;
 16: 
 17: namespace Depreciation
 18: {
 19:     /// <summary>
 20:     /// Interaction logic for Window1.xaml
 21:     /// </summary>
 22:     public partial class Window1 : Window
 23:     {
 24:         public Window1()
 25:         {
 26:             InitializeComponent();
 27:             DataContext = new MyViewModel();
 28:         }
 29:     }
 30: 
 31:     public class MyViewModel : INotifyPropertyChanged
 32:     {
 33:         private DepreciationList _depreciationList;
 34:         private DepreciationInput _depreciationInput;
 35:         public event PropertyChangedEventHandler PropertyChanged;
 36: 
 37:         public MyViewModel()
 38:         {
 39:             _depreciationList = new DepreciationList();
 40:             _depreciationInput = new DepreciationInput();
 41:             CalculateDepreciationCommand = new MyCommand(CalculateDepreciation);
 42:         }
 43: 
 44:         public DepreciationList DepreciationList
 45:         {
 46:             get
 47:             {
 48:                 return _depreciationList;
 49:             }
 50:             set
 51:             {
 52:                 _depreciationList = value;
 53:                 RaisePropertyChanged("DepreciationList");
 54:             }
 55:         }
 56: 
 57:         public DepreciationInput DepreciationInput
 58:         {
 59:             get
 60:             {
 61:                 return _depreciationInput;
 62:             }
 63:             set
 64:             {
 65:                 _depreciationInput = value;
 66:                 RaisePropertyChanged("DepreciationInput");
 67:             }
 68:         }
 69: 
 70:         private void RaisePropertyChanged(string propertyName)
 71:         {
 72:             PropertyChangedEventHandler handler = this.PropertyChanged;
 73: 
 74:             if (handler != null)
 75:             {
 76:                 handler(this, new PropertyChangedEventArgs(propertyName));
 77:             }
 78:         }
 79: 
 80:         public ICommand CalculateDepreciationCommand
 81:         { get; set; }
 82: 
 83:         public bool CalculateDepreciation()
 84:         {
 85: 
 86:             _depreciationList.Clear();
 87: 
 88:             int year = DepreciationInput.LifeSpan;
 89:             double cost = DepreciationInput.FixedAssets;
 90:             double scrap = DepreciationInput.ScrapValue;
 91: 
 92:             if (year <= 0)
 93:             {
 94:                 return false; ;
 95:             }
 96: 
 97:             if (cost <= 0 || scrap <= 0)
 98:             {
 99:                 return false;
100:             }
101: 
102:             double accDepreciation = 0;
103:             double bookValue = cost - scrap;
104:             double depExpense = 0;
105:             int sum = year * (year + 1) / 2;
106:             int totalYears = year;
107: 
108:             for (int iIndex = 0; iIndex < year; iIndex++)
109:             {
110:                 double percentage = (double)totalYears / (double)sum;
111: 
112:                 depExpense = bookValue * percentage;
113:                 cost -= depExpense;
114:                 accDepreciation += depExpense;
115: 
116:                 DepreciationInfo dpInfo = new DepreciationInfo();
117:                 dpInfo.Year = (iIndex + 1);
118:                 dpInfo.Depreciation = depExpense;
119:                 dpInfo.AccDepreciation = accDepreciation;
120:                 dpInfo.BookValue = cost;
121:                 dpInfo.Percentage = percentage * 100;
122: 
123:                 _depreciationList.Add(dpInfo);
124:                 totalYears--;
125:             }
126: 
127:             return true;
128:         }
129:     }
130: 
131:     public class MyCommand : ICommand
132:     {
133:         public Func<bool> Function
134:         { get; set; }
135: 
136:         public MyCommand()
137:         {
138:         }
139: 
140:         public MyCommand(Func<bool> function)
141:         {
142:             Function = function;
143:         }
144: 
145:         public bool CanExecute(object parameter)
146:         {
147:             if (Function != null)
148:             {
149:                 return true;
150:             }
151: 
152:             return false;
153:         }
154: 
155:         public void Execute(object parameter)
156:         {
157:             if (Function != null)
158:             {
159:                 Function();
160:             }
161:         }
162: 
163:         public event EventHandler CanExecuteChanged
164:         {
165:             add { CommandManager.RequerySuggested += value; }
166:             remove { CommandManager.RequerySuggested -= value; }
167:         }
168:     }
169: 
170:     public class DepreciationInput : DependencyObject
171:     {
172:         public static readonly DependencyProperty FixedAssetsProperty =
173:             DependencyProperty.Register("FixedAssets", typeof(double), typeof(DepreciationInput));
174: 
175:         public static readonly DependencyProperty LifeSpanProperty =
176:             DependencyProperty.Register("LifeSpan", typeof(int), typeof(DepreciationInput));
177: 
178:         public static readonly DependencyProperty ScrapValueProperty =
179:             DependencyProperty.Register("ScrapValue", typeof(double), typeof(DepreciationInput));
180: 
181:         public double FixedAssets
182:         {
183:             get { return (double)GetValue(FixedAssetsProperty); }
184:             set { SetValue(FixedAssetsProperty, value); }
185:         }
186: 
187:         public int LifeSpan
188:         {
189:             get { return (int)GetValue(LifeSpanProperty); }
190:             set { SetValue(LifeSpanProperty, value); }
191:         }
192: 
193:         public double ScrapValue
194:         {
195:             get { return (double)GetValue(ScrapValueProperty); }
196:             set { SetValue(ScrapValueProperty, value); }
197:         }
198:     }
199: 
200:     public class DepreciationInfo
201:     {
202:         public int Year
203:         { get; set; }
204: 
205:         public double Depreciation
206:         { get; set; }
207: 
208:         public double AccDepreciation
209:         { get; set; }
210: 
211:         public double BookValue
212:         { get; set; }
213: 
214:         public double Percentage
215:         { get; set; }
216:     }
217: 
218:     public class DepreciationList : ObservableCollection<DepreciationInfo>
219:     {
220:     }
221: }
222: 

This is the output of the program.

MVVM_Depreciation_Output


Responses

  1. […] encoding using MVVM We have already saw few example of MVVM here and here. But in both example we were using the Func class to implement the ICommand interface. Now we are […]

  2. I feel so lucky to find out this great blog. Thank you very much for posting this helpful topic.I really appreciate your work

    • Thanks to like this blog.


Leave a reply to String encoding using MVVM « Zeeshan Amjad's WPF Blog Cancel reply

Categories