We have already seen the example of using MVVM using INotifyPropertyChange interface. But we can do the same thing with dependency property. Here is our same model class, but this time instead of implementing INotifyPropertyChange interface, we are going to make its properties dependency properties. Here is a piece of code to make these properties as Dependency Property.
1: public class Numbers : DependencyObject2: {3: public static readonly DependencyProperty FirstNoProperty =4: DependencyProperty.Register("FirstNo", typeof(int), typeof(Numbers));5:6: public static readonly DependencyProperty SecondNoProperty =7: DependencyProperty.Register("SecondNo", typeof(int), typeof(Numbers));8:9: public static readonly DependencyProperty ResultProperty =10: DependencyProperty.Register("Result", typeof(int), typeof(Numbers));11:12: public static readonly DependencyProperty ResultLabelProperty =13: DependencyProperty.Register("ResultLabel", typeof(String), typeof(Numbers));14:15: public int FirstNo16: {17: get { return (int)GetValue(FirstNoProperty); }18: set { SetValue(FirstNoProperty, value); }19: }20:21: public int SecondNo22: {23: get { return (int)GetValue(SecondNoProperty); }24: set { SetValue(SecondNoProperty, value); }25: }26:27: public String ResultLabel
28: {29: get { return (String)GetValue(ResultLabelProperty); }30: set { SetValue(ResultLabelProperty, value); }31: }32:33: public int Result34: {35: get { return (int)GetValue(ResultProperty); }36: set { SetValue(ResultProperty, value); }37: }38: }39:Rest of the program is same as previous program. Here is a complete XAML code of our program.
1: <Window x:Class="WpfCommandBinding.Window1"2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"4: xmlns:local="clr-namespace:WpfCommandBinding"5: Title="MVVM" Height="200" Width="300">6: <Grid Name="grid" Background="Wheat">7: <Grid.ColumnDefinitions>8: <ColumnDefinition/>9: <ColumnDefinition/>10: </Grid.ColumnDefinitions>11: <Grid.RowDefinitions>12: <RowDefinition/>13: <RowDefinition/>14: <RowDefinition/>15: <RowDefinition/>16: </Grid.RowDefinitions>17: <TextBlock Grid.Column="0" Grid.Row="0" Margin="5"18: VerticalAlignment="Center" Text="Enter first number"/>19: <TextBox Grid.Column="1" Grid.Row="0" Margin="5"20: VerticalAlignment="Center" Text="{Binding Path=Numbers.FirstNo}"/>21: <TextBlock Grid.Column="0" Grid.Row="1" Margin="5"22: VerticalAlignment="Center" Text="Enter second number"/>23: <TextBox Grid.Column="1" Grid.Row="1" Margin="5"24: VerticalAlignment="Center" Text="{Binding Path=Numbers.SecondNo}"/>25: <TextBlock Grid.Column="0" Grid.Row="2" Margin="5"26: VerticalAlignment="Center" Text="{Binding Path=Numbers.ResultLabel}"/>27: <TextBlock Grid.Column="1" Grid.Row="2" Margin="5"28: VerticalAlignment="Center" Text="{Binding Path=Numbers.Result}"/>29: <Button Grid.Column="0" Grid.Row="3" Margin="5"30: Content="GCD" Command="{Binding CalculateGCDCommand}"/>31: <Button Grid.Column="1" Grid.Row="3" Margin="5"32: Content="LCM" Command="{Binding CalculateLCMCommand}"/>33: </Grid>34: </Window>35:Here is complete C# code of 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.ComponentModel;15:16: namespace WpfCommandBinding17: {18: /// <summary>19: /// Interaction logic for Window1.xaml20: /// </summary>21: public partial class Window1 : Window22: {23: private Numbers nos = new Numbers();24:25: public Window1()26: {27: InitializeComponent();28:29: DataContext = new MyViewModel();30: }31: }32:33: public class MyViewModel : INotifyPropertyChanged34: {35: private Numbers _numbers;36: public event PropertyChangedEventHandler PropertyChanged;37:38: public MyViewModel()39: {40: _numbers = new Numbers();41: CalculateGCDCommand = new MyCommand(CalculateGCD);42: CalculateLCMCommand = new MyCommand(CalculateLCM);43: }44:45: public Numbers Numbers46: {47: get48: {49: return _numbers;50: }51: set52: {53: _numbers = value;54: RaisePropertyChanged("Numbers");55: }56: }57:58: private void RaisePropertyChanged(string propertyName)59: {60: PropertyChangedEventHandler handler = this.PropertyChanged;61:62: if (handler != null)63: {64: handler(this, new PropertyChangedEventArgs(propertyName));65: }66: }67:68: public ICommand CalculateGCDCommand69: { get; set; }70:71: public ICommand CalculateLCMCommand72: { get; set; }73:74: private int CalculateGCD()75: {76: int x = Numbers.FirstNo;77: int y = Numbers.SecondNo;78:79: Numbers.Result = CalculateGCDInternal(x, y);80: Numbers.ResultLabel = "GCD";81:82: return Numbers.Result;83: }84:85: private int CalculateGCDInternal(int x, int y)86: {87: if (x == 0)88: return 0;89:90: while (y != 0)91: {92: if (x > y)93: x = x - y;94: else95: y = y - x;96: }97:98: return x;99: }100:101: private int CalculateLCM()102: {103: int x = Numbers.FirstNo;104: int y = Numbers.SecondNo;105:106: int lcm = x * y / CalculateGCDInternal(x, y);107:108: Numbers.Result = lcm;109: Numbers.ResultLabel = "LCM";110: return lcm;111: }112: }113:114: public class MyCommand : ICommand115: {116: public Func<int> Function117: { get; set; }118:119: public MyCommand()120: {121: }122:123: public MyCommand(Func<int> function)124: {125: Function = function;126: }127:128: public bool CanExecute(object parameter)129: {130: if (Function != null)131: {132: return true;133: }134:135: return false;136: }137:138:139: public void Execute(object parameter)140: {141: if (Function != null)142: {143: Function();144: }145: }146:147: public event EventHandler CanExecuteChanged148: {149: add { CommandManager.RequerySuggested += value; }150: remove { CommandManager.RequerySuggested -= value; }151: }152: }153:154: public class Numbers : DependencyObject155: {156: public static readonly DependencyProperty FirstNoProperty =157: DependencyProperty.Register("FirstNo", typeof(int), typeof(Numbers));158:159: public static readonly DependencyProperty SecondNoProperty =160: DependencyProperty.Register("SecondNo", typeof(int), typeof(Numbers));161:162: public static readonly DependencyProperty ResultProperty =163: DependencyProperty.Register("Result", typeof(int), typeof(Numbers));164:165: public static readonly DependencyProperty ResultLabelProperty =166: DependencyProperty.Register("ResultLabel", typeof(String), typeof(Numbers));167:168: public int FirstNo169: {170: get { return (int)GetValue(FirstNoProperty); }171: set { SetValue(FirstNoProperty, value); }172: }173:174: public int SecondNo175: {176: get { return (int)GetValue(SecondNoProperty); }177: set { SetValue(SecondNoProperty, value); }178: }179:180: public String ResultLabel181: {182: get { return (String)GetValue(ResultLabelProperty); }183: set { SetValue(ResultLabelProperty, value); }184: }185:186: public int Result187: {188: get { return (int)GetValue(ResultProperty); }189: set { SetValue(ResultProperty, value); }190: }191: }192: }193:Here is the output of the program when we click on the GCD.
And here is the output of the program when click on LCM.
[…] 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 […]
By: Calculate Depreciation using MVVM Pattern « Zeeshan Amjad's WPF Blog on January 24, 2010
at 12:51 am
[…] 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 […]
By: String encoding using MVVM « Zeeshan Amjad's WPF Blog on February 27, 2010
at 12:34 am
Thanks for this nice Tutorial !
was very helpful for me.
By: Mike on November 8, 2010
at 11:15 am
… would be helpful if you could post the getValue / setValue Methods – i don’t know where to implement them (see property setters)
By: Mike on November 9, 2010
at 6:53 am
May be i didn’t understand your question. I didn’t implement GetValue and SetValue methods. These methods are in fact in DependencyObject class. When we inherit class from DependencyObject (One basic requirement to create dependency properties) then we automatically get these methods.
By: zamjad on December 16, 2010
at 8:48 am
Hi!
Thanks for this post. I have a question. What concerns me, is that if we really should mix very UI specific mechanisms, like DependencyProperties, with your model?
I think the point to surface a model, which consists of POCOs, to a view with properties on a viewmodel, that has an ability to notify any changes to the view. Moreover, I think the only place where you should be using DependencyPropeties is the view.
Do you have any convincing arguments for following your way?
Regards,
macqm
By: macqm on July 27, 2011
at 4:11 am
Hi
Thanks to like this. Yes i understand your concern and you have a valid point that dependency property should be related to UI. In this post i justed wanted to show that theoritically it is possible to use the notification in two ways, one is INotifyPropertyChanged interface (which i discussed in another post) and other is dependency property, which i discussed here. In fact in few of my posts when i created a base class for ViewModel i used the INotifyPropertyChanged interface not dependency property.
Thanks to bring this on to avoid any confusion for future reader of this article.
Regards
Zeeshan Amjad
By: zamjad on July 27, 2011
at 12:46 pm
Hi Zeeshan,
I like your article. Very interresting.
Regarding your answer to macqm, I think that the main advantage of DependencyProperty over INPC interface is for creating userControl to make dataBinding easier.
But I have a concern… probably due to my ignorance, I wonder if there is anything that would’nt work properly if the propertyObject is defined in the model instead of directly under the control itself. There wouldn’t be a link between the dp and it’s parent control ???
Regards,
Eric
By: ericouellet2 on October 18, 2011
at 9:53 am
Hi Eric
Thanks to like my article and thinks for giving more clear and indepth answer to macqm. I came across an interesting article that discuss the same issue in more depth. View Models: POCOs versus DependencyObjects. I hope you find it interesting too.
Regards
Zeeshan Amjad
By: Zeeshan Amjad on October 18, 2011
at 10:30 am
Thanks Zeeshan,
After reading part of the link I was a bit shock…
I’m crude but I think that Boogart has few things wrong…
Too me it is simple, DPs for every property of userControl, otherwise we should use INotifyPropertyChange (many reasons explain that but it will be too long too explain).
Also, View Model inheritance, too me, is a non-sense. And more…
But i’m not sure i’m right..
Thanks for your help and your article and good luck !
By: ericouellet2 on October 18, 2011
at 1:31 pm
Ho also, if the DP is not in the userControl (ie in the viewModel) then you would not be able to bind to it (either through VS designer or code).
By: ericouellet2 on October 18, 2011
at 1:35 pm
Is it interesting use the Dependency Properties also on ViewModel Layer? Or just in Model layer? Your website is incredible… Congrats…
By: RafaelFerreira on June 1, 2014
at 4:08 pm
Thanks for visiting and like my blog. Usually dependency property is not used in Models. Model usually implement INotifyPropertyChanged interface. Dependency property is usually more useful in UserControl.
By: Zeeshan Amjad on November 9, 2014
at 10:46 pm
Hello,
I would like to add other property in ViewModel with RaisePropertyChanged.
How can I track changes on dependencyProperty and binding to other property(‘Result’ with other property ‘VmProp’)?
View :
VM:
public int VmProp
{
get { return vmProp; }
set
{
vmProp = value;
RaisePropertyChanged(“VmProp”);
}
}
By: Leonid on November 23, 2016
at 1:30 pm