myHealth
I recently had a friend of mine (who is a professional bodybuilder), ask me to write him a simple application with which he can track his training progress?
Here is some of the things I learned while writing myHealth
INotifyPropertyChanged vs DependencyObject
The PropertyGrid I used unfortunately only work with dependency properties (DependencyObject) so I had to choose them! My personal preference would have been the lighter weight INotifyPropertyChanged. Here are the pro's and con's of both
DependencyObject
- .NET 3.0 or better
- Can't be serialized (THIS SUCKS)
- Extra overhead (Dispatcher)
+ DependencyProperty Features: Coercion, Property changes notification, Spars storage, Validation, optimized for data binding, etc
INotifyPropertyChanged
+ .NET 2.0 or better
+ Serializable
+ Lightweight
When select between DependencyObject vs INotifyPropertyChanged, you should also put it into context of where it would be used... Are you creating a Model, Business Object, Domain Object, etc... Some of the cons don't then apply!
Although I was forced to use DO's, the fact that I had to manually store my data was a huge pain in the ...
Check out the full discussion on the WPF Disciples news group
PropertyGrid
I used Denis Vuyka's excellent PropertyGrid! The only drawback of using this PropertyGrid was that it only worked with dependency properties! To use the PropertyGrid, add the following namespace
xmlns:dv="clr-namespace:DenisVuyka.Controls.PropertyGrid;assembly=DenisVuyka.Controls.PropertyGrid"
and use it as follows
<dv:PropertyGrid SelectedObject="{Binding Path=SelectedItem, ElementName=assesmentsListBox}" ExpandCategories="False" />
The SelectedObject can be any DependencyObject derived class, here I bind it to the current selected Assesment.
The category header is determined by the following attribute on the DP CLR Property wrappers
[Category("Assesment")]
IsolatedStorage
myHealth uses IsolatedStorage (Domain) as the storage medium for the assesment history
IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForDomain();
IsolatedStorageFileStream stream = newIsolatedStorageFileStream("assesments.xml", FileMode.Open, file);
Drag & Drop
Drag & Drop in WPF is extremely easy... I added the following to my window
AllowDrop="True"
Drop="Window_Drop"
And here is my Drop event handler
private void Window_Drop(object sender, DragEventArgs e)
{
string[] fileNames = e.Data.GetData(DataFormats.FileDrop, true) as string[];
foreach (string fileName in fileNames)
{
...
}
}
Now you can drag & drop pictures into myHealth!!!
TODO: Check the file extension of file being dropped... make sure that it is a .JPG file!!!
Structural Skinning
myHealth also supports structural skinning. I am currently creating a extra skin using Blendables Timeline layout panel which will lay out the assessments on a timeline!
DrawingBrush
myHealth uses a DrawingBrush as the default background for the progress pictures ListBox... This is similar to what popular programs like Blend use.
Zoom, Zoom, Zoom...
The Zoom is a simple UIElement binding between the Slider.Value and the ScaleTransform.X and ScaleTransform.Y of my images in my ListBox!
Code Analytics
Source Analysis (StyleCop) is a new product recently released by Microsoft. Although only recently released, this product has been used internally by Microsoft for years! The program helps enforce uniform and easily maintainable code! Since myHealth will be released on CodePlex, I decided to give it a try...
Disabled the following rules:
- C# -> Analyze design files
These files are created by Visual Studio...
SA1201
- C# -> Readability Rules -> Method Parameter Placement
SA1115, SA1116, SA1117
Dr WPF's dependency property snippets current violate these rules...
- C# -> Documentation Rules -> Element Documentation
SA1600
- C# -> Documentation Rules -> File Headers
All
Source
The source is released on CodePlex