<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4984249252218519917</id><updated>2012-01-28T23:00:26.580-06:00</updated><category term='c#'/><category term='mobile'/><category term='C++'/><category term='.net-4'/><category term='bluetooth'/><category term='yum'/><category term='m4a'/><category term='iTunes'/><category term='fish'/><category term='whs'/><category term='silverlight'/><category term='wpf'/><category term='webos'/><category term='tablet'/><category term='trace'/><category term='CodeProject'/><category term='.net'/><category term='windows-phone-7'/><category term='code'/><category term='google-code'/><category term='XNA'/><category term='vail'/><category term='alpha-blending'/><title type='text'>Spooky Coding at a Distance</title><subtitle type='html'>Random babblings about creating, using and generally considering software.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>25</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-1734024917314730536</id><published>2012-01-28T16:19:00.003-06:00</published><updated>2012-01-28T16:45:18.864-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='windows-phone-7'/><title type='text'>A slightly less simple object browser for windows phone 7</title><content type='html'>Building slightly on the previous post we can drill into properties and navigate back up the parent tree.The Xaml adds some styling and a couple of hyperlinks:&lt;pre class="brush: xml"&gt;&lt;br /&gt;&amp;lt;UserControl x:Class="GoogleAuthDemo.ObjectBrowser"&lt;br /&gt;    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;br /&gt;    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&lt;br /&gt;    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"&lt;br /&gt;    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"&lt;br /&gt;    xmlns:local="clr-namespace:GoogleAuthDemo"&lt;br /&gt;    mc:Ignorable="d"&lt;br /&gt;    FontFamily="{StaticResource PhoneFontFamilyNormal}"&lt;br /&gt;    FontSize="{StaticResource PhoneFontSizeNormal}"&lt;br /&gt;    Foreground="{StaticResource PhoneForegroundBrush}"&lt;br /&gt;    d:DesignHeight="480" d:DesignWidth="480"&lt;br /&gt;    x:Name="root"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;UserControl.Resources&amp;gt;&lt;br /&gt;        &amp;lt;local:ObjectPropertiesConverter x:Key="ObjectPropertiesConvert"/&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;Style x:Key="PropertyStyle" TargetType="HyperlinkButton"&amp;gt;&lt;br /&gt;         &amp;lt;Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/&amp;gt;&lt;br /&gt;         &amp;lt;Setter Property="Background" Value="Transparent"/&amp;gt;&lt;br /&gt;         &amp;lt;Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}"/&amp;gt;&lt;br /&gt;         &amp;lt;Setter Property="Padding" Value="0"/&amp;gt;&lt;br /&gt;         &amp;lt;Setter Property="Template"&amp;gt;&lt;br /&gt;          &amp;lt;Setter.Value&amp;gt;&lt;br /&gt;           &amp;lt;ControlTemplate TargetType="HyperlinkButton"&amp;gt;&lt;br /&gt;            &amp;lt;Border Background="Transparent"&amp;gt;&lt;br /&gt;             &amp;lt;VisualStateManager.VisualStateGroups&amp;gt;&lt;br /&gt;              &amp;lt;VisualStateGroup x:Name="CommonStates"&amp;gt;&lt;br /&gt;               &amp;lt;VisualState x:Name="Normal"&amp;gt;&lt;br /&gt;                &amp;lt;Storyboard&amp;gt;&lt;br /&gt;                 &amp;lt;ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="TextElement"&amp;gt;&lt;br /&gt;                  &amp;lt;DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/&amp;gt;&lt;br /&gt;                 &amp;lt;/ObjectAnimationUsingKeyFrames&amp;gt;&lt;br /&gt;                &amp;lt;/Storyboard&amp;gt;      &lt;br /&gt;         &amp;lt;/VisualState&amp;gt;&lt;br /&gt;               &amp;lt;VisualState x:Name="MouseOver"/&amp;gt;&lt;br /&gt;               &amp;lt;VisualState x:Name="Pressed"&amp;gt;&lt;br /&gt;                &amp;lt;Storyboard&amp;gt;&lt;br /&gt;                 &amp;lt;DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="TextElement"/&amp;gt;&lt;br /&gt;                &amp;lt;/Storyboard&amp;gt;&lt;br /&gt;               &amp;lt;/VisualState&amp;gt;&lt;br /&gt;               &amp;lt;VisualState x:Name="Disabled"&amp;gt;&lt;br /&gt;                &amp;lt;Storyboard&amp;gt;&lt;br /&gt;                 &amp;lt;ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="TextElement"&amp;gt;&lt;br /&gt;                  &amp;lt;DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/&amp;gt;&lt;br /&gt;                 &amp;lt;/ObjectAnimationUsingKeyFrames&amp;gt;&lt;br /&gt;                &amp;lt;/Storyboard&amp;gt;&lt;br /&gt;               &amp;lt;/VisualState&amp;gt;&lt;br /&gt;              &amp;lt;/VisualStateGroup&amp;gt;&lt;br /&gt;             &amp;lt;/VisualStateManager.VisualStateGroups&amp;gt;&lt;br /&gt;             &amp;lt;Border Background="{TemplateBinding Background}" Margin="{StaticResource PhoneHorizontalMargin}" Padding="{TemplateBinding Padding}"&amp;gt;&lt;br /&gt;              &amp;lt;TextBlock x:Name="TextElement" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Text="{TemplateBinding Content}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/&amp;gt;&lt;br /&gt;             &amp;lt;/Border&amp;gt;&lt;br /&gt;            &amp;lt;/Border&amp;gt;&lt;br /&gt;           &amp;lt;/ControlTemplate&amp;gt;&lt;br /&gt;          &amp;lt;/Setter.Value&amp;gt;&lt;br /&gt;         &amp;lt;/Setter&amp;gt;&lt;br /&gt;        &amp;lt;/Style&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;DataTemplate x:Key="PropertyTemplate"&amp;gt;&lt;br /&gt;            &amp;lt;StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch"&amp;gt;&lt;br /&gt;                &amp;lt;TextBlock Text="{Binding Name}" Margin="0,0,10,1"/&amp;gt;&lt;br /&gt;                     &amp;lt;HyperlinkButton HorizontalAlignment="Right" &lt;br /&gt;                    IsEnabled="{Binding HasChildren}"&lt;br /&gt;                    Content="{Binding Value}"                    &lt;br /&gt;                    Click="HyperlinkButton_Click" Style="{StaticResource PropertyStyle}"/&amp;gt;&lt;br /&gt;&lt;br /&gt;            &amp;lt;/StackPanel&amp;gt;&lt;br /&gt;        &amp;lt;/DataTemplate&amp;gt;&lt;br /&gt;    &amp;lt;/UserControl.Resources&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;StackPanel Orientation="Vertical"&amp;gt;&lt;br /&gt;        &amp;lt;HyperlinkButton Content="&amp;lt; Back" Foreground="{StaticResource PhoneAccentBrush}" HorizontalAlignment="Left"&lt;br /&gt;             IsEnabled="{Binding ElementName=root, Path=CanBack}"&lt;br /&gt;                         Click="BackButton_Click" FontWeight="Bold" FontStyle="Normal"/&amp;gt;&lt;br /&gt;        &amp;lt;ScrollViewer&amp;gt;&lt;br /&gt;            &amp;lt;ItemsControl ItemTemplate="{StaticResource PropertyTemplate}"&lt;br /&gt;                      ItemsSource="{Binding Path=., Converter={StaticResource ObjectPropertiesConvert}}"&amp;gt;&lt;br /&gt;            &amp;lt;/ItemsControl&amp;gt;&lt;br /&gt;        &amp;lt;/ScrollViewer&amp;gt;&lt;br /&gt;    &amp;lt;/StackPanel&amp;gt;&lt;br /&gt;&amp;lt;/UserControl&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Then we need to add little bit to the control code behind to handle forward and backward navigation:&lt;pre class="brush: c#"&gt;&lt;br /&gt;    public partial class ObjectBrowser : UserControl&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        public ObjectBrowser()&lt;br /&gt;        {&lt;br /&gt;            InitializeComponent();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private Stack&amp;lt;object&amp;gt; _backStack = new Stack&amp;lt;object&amp;gt;();&lt;br /&gt;&lt;br /&gt;        private void HyperlinkButton_Click(object sender, RoutedEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            if (this.DataContext != null)&lt;br /&gt;            {&lt;br /&gt;                _backStack.Push(this.DataContext);&lt;br /&gt;                CanBack = true;&lt;br /&gt;            }&lt;br /&gt;            ObjectProperty p = ((HyperlinkButton)sender).DataContext as ObjectProperty;&lt;br /&gt;            if (p != null)&lt;br /&gt;                this.DataContext = p.TheObject;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void BackButton_Click(object sender, RoutedEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            if (_backStack.Count &gt; 0)&lt;br /&gt;            {&lt;br /&gt;                DataContext = _backStack.Pop();&lt;br /&gt;                CanBack = _backStack.Count &gt; 0;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// The &lt;see cref="CanBack" /&gt; dependency property's name.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public const string CanBackPropertyName = "CanBack";&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Gets or sets the value of the &lt;see cref="CanBack" /&gt;&lt;br /&gt;        /// property. This is a dependency property.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public bool CanBack&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return (bool)GetValue(CanBackProperty);&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                SetValue(CanBackProperty, value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Identifies the &lt;see cref="CanBack" /&gt; dependency property.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public static readonly DependencyProperty CanBackProperty = DependencyProperty.Register(&lt;br /&gt;            CanBackPropertyName,&lt;br /&gt;            typeof(bool),&lt;br /&gt;            typeof(ObjectBrowser),&lt;br /&gt;            new PropertyMetadata(false));&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;And we still need this converter class to take an object and break out its properties into something we can enumerate over to get theproperty name and instance's value:&lt;pre class="brush: c#"&gt;&lt;br /&gt;    public class ObjectPropertiesConverter : IValueConverter&lt;br /&gt;    {&lt;br /&gt;        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)&lt;br /&gt;        {&lt;br /&gt;            if (value == null)&lt;br /&gt;                return null;&lt;br /&gt;&lt;br /&gt;            return from p in value.GetType().GetProperties()&lt;br /&gt;                   where p.CanRead &amp;&amp; p.GetIndexParameters().Count() == 0 // skip indexer properties&lt;br /&gt;                   select new ObjectProperty&lt;br /&gt;                   {&lt;br /&gt;                       Name = p.Name,&lt;br /&gt;                       TheObject = p.GetValue(value, null)&lt;br /&gt;                   };&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)&lt;br /&gt;        {&lt;br /&gt;            throw new NotImplementedException();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;But we're going to replace the KeyValuePair with a small helper class. This is what each row in the browser will bind to and it keeps the actual object around to support navigation through the tree:&lt;pre class="brush: c#"&gt;&lt;br /&gt;    public class ObjectProperty&lt;br /&gt;    {&lt;br /&gt;        public object TheObject { get; set; }&lt;br /&gt;        public string Name { get; set; }&lt;br /&gt;        public string Value&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return TheObject != null ? TheObject.ToString() : "(null)";&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public bool HasChildren&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                if (TheObject != null)&lt;br /&gt;                    return !TheObject.GetType().IsValueType;// &amp;&amp; !(TheObject is string);&lt;br /&gt;&lt;br /&gt;                return false;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;So with that you should be able to navigate object hierarchies from within the phone app at runtime. I wouldn't use it in an app but I'm hoping it will be good debugging and rapid prototyping tool so I can build the data layer and rought UI structure and then deal with UI styling later.&lt;br/&gt;** warning - I'm posting as I code this so test coverage is well, um... limited **&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Membership/View.aspx?mid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-1734024917314730536?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/1734024917314730536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2012/01/slightly-less-simple-object-browser-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/1734024917314730536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/1734024917314730536'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2012/01/slightly-less-simple-object-browser-for.html' title='A slightly less simple object browser for windows phone 7'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-8231887444255139112</id><published>2012-01-28T14:15:00.001-06:00</published><updated>2012-01-28T16:38:52.214-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>A simple SilverLight object viewer</title><content type='html'>Sometimes when you're making a windows phone 7 rest client you just want to look at some of the returned data to poke see what's there. You can wire up some ui or use tracing. Maybe some breakpoints. But it's also nice to be able to drop something into the UI that you can access easily and as needed.The WinForms object browser is a handy for instance for debugging things at runtime, within the app without a debugger or a designed UI.This little widget isn't as fully functional as taht but can be helpful in a similar way. Drop it somewhere in the UI and set its DataContext property and all public readable properies will be listed with name and value.First some XAML&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;UserControl x:Class="GoogleAuthDemo.ObjectBrowser"&lt;br /&gt;    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;br /&gt;    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&lt;br /&gt;    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"&lt;br /&gt;    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"&lt;br /&gt;    xmlns:local="clr-namespace:GoogleAuthDemo"&lt;br /&gt;    mc:Ignorable="d"&lt;br /&gt;    FontFamily="{StaticResource PhoneFontFamilyNormal}"&lt;br /&gt;    FontSize="{StaticResource PhoneFontSizeNormal}"&lt;br /&gt;    Foreground="{StaticResource PhoneForegroundBrush}"&lt;br /&gt;    d:DesignHeight="480" d:DesignWidth="480"&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;UserControl.Resources&amp;gt;&lt;br /&gt;        &amp;lt;local:ObjectPropertiesConverter x:Key="ObjectPropertiesConvert"/&amp;gt;&lt;br /&gt;        &lt;br /&gt;        &amp;lt;DataTemplate x:Key="PropertyTemplate"&amp;gt;&lt;br /&gt;            &amp;lt;StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch"&amp;gt;&lt;br /&gt;                &amp;lt;TextBlock Text="{Binding Key}" Margin="0,0,10,1"/&amp;gt;&lt;br /&gt;                &amp;lt;TextBlock Text="{Binding Value}" TextWrapping="Wrap" TextAlignment="Right" HorizontalAlignment="Right" /&amp;gt;&lt;br /&gt;            &amp;lt;/StackPanel&amp;gt;&lt;br /&gt;        &amp;lt;/DataTemplate&amp;gt;&lt;br /&gt;    &amp;lt;/UserControl.Resources&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;ScrollViewer&amp;gt;&lt;br /&gt;        &amp;lt;ItemsControl ItemTemplate="{StaticResource PropertyTemplate}"&lt;br /&gt;                      ItemsSource="{Binding Path=., Converter={StaticResource ObjectPropertiesConvert}}"&amp;gt;                &lt;br /&gt;        &amp;lt;/ItemsControl&amp;gt;&lt;br /&gt;    &amp;lt;/ScrollViewer&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/UserControl&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;With a smidge of C# to create a name value pair collection, given an object's properties&lt;br /&gt;&lt;pre class="brush: c#"&gt;    public class ObjectPropertiesConverter : IValueConverter&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)&lt;br /&gt;        {&lt;br /&gt;            if (value == null)&lt;br /&gt;                return null;&lt;br /&gt;&lt;br /&gt;            return from p in value.GetType().GetProperties()&lt;br /&gt;                   where p.CanRead&lt;br /&gt;                   select new KeyValuePair&amp;lt;string, string&amp;gt;&lt;br /&gt;                   (&lt;br /&gt;                      p.Name,&lt;br /&gt;                      p.GetValue(value, null) != null ? p.GetValue(value, null).ToString() : null&lt;br /&gt;                   );                   &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)&lt;br /&gt;        {&lt;br /&gt;            throw new NotImplementedException();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Membership/View.aspx?mid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-8231887444255139112?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/8231887444255139112/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2012/01/simple-silverlight-object-viewer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/8231887444255139112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/8231887444255139112'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2012/01/simple-silverlight-object-viewer.html' title='A simple SilverLight object viewer'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-1169226145405399663</id><published>2011-12-29T11:37:00.003-06:00</published><updated>2011-12-29T11:37:23.501-06:00</updated><title type='text'></title><content type='html'>I'm gonna try &lt;a href="http://twitter.com/#!/Dkackman"&gt;this twitter thing&lt;/a&gt; that all the kids ahve been talking about.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-1169226145405399663?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/1169226145405399663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2011/12/im-gonna-try-this-twitter-thing-that.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/1169226145405399663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/1169226145405399663'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2011/12/im-gonna-try-this-twitter-thing-that.html' title=''/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-3414415040217358627</id><published>2011-12-17T10:09:00.000-06:00</published><updated>2011-12-17T10:34:24.225-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webos'/><category scheme='http://www.blogger.com/atom/ns#' term='tablet'/><title type='text'>WebOS? I like it...</title><content type='html'>So I picked up one of those &lt;a href="http://www.hp.com/united-states/webos/us/en/index.html"&gt;HP TouchPads&lt;/a&gt; from their latest eBay firesale for $150. Mostly intended as a much nerdier replacement for an iPad. Root it, put Android on it, play around with other linux tablet builds, even get Windows 8 on there as soon as that's possible. At a $150 I'm much more comfortable taking the risk of bricking this thing than say the $5-600 pricetag of similar hardware.&lt;br /&gt;&lt;br /&gt;So anyway, after a few days of playing around with it and the &lt;a href="http://rootzwiki.com/topic/10121-releasealpha35cyanogenmod-touchpad/"&gt;cyanogenmod 7&lt;/a&gt; build I have to say of the 3 tablet OS's (IOS, WebOS, Android) that I've used WebOS is the most compelling. It's prettier and slicker than IOS and definately better organized and usable than Android. Maybe it's the newness of it for me, but i just plain "like it".&lt;br /&gt;&lt;br /&gt;If I had to choose a single OS for every day tablet use (and I do use my tablet every day at work and home) WebOS is the easy first choice for me. If it had word's with friends and stumbleupon I wouldn't even hestiate.&lt;br /&gt;&lt;br /&gt;Let's hope that HP's decision to open source it giives it some legs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-3414415040217358627?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/3414415040217358627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2011/12/webos-i-like-it.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/3414415040217358627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/3414415040217358627'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2011/12/webos-i-like-it.html' title='WebOS? I like it...'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-3471534848557654312</id><published>2011-04-03T12:13:00.001-05:00</published><updated>2011-04-03T12:14:20.838-05:00</updated><title type='text'>I couldn't agree more</title><content type='html'>From Linus Torvalds' &lt;a href="http://www.chris-lott.org/resources/cstyle/LinuxKernelCodingStyle.txt"&gt;Linux Kernel style guide&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Now, some people will claim that having 8-character indentations makes&lt;br /&gt;the code move too far to the right, and makes it hard to read on a&lt;br /&gt;80-character terminal screen.  The answer to that is that if you need&lt;br /&gt;more than 3 levels of indentation, you're screwed anyway, and should fix&lt;br /&gt;your program. &lt;br /&gt;&lt;br /&gt;In short, 8-char indents make things easier to read, and have the added&lt;br /&gt;benefit of warning you when you're nesting your functions too deep. &lt;br /&gt;Heed that warning. &lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;It amazes me how many professional software engineers don't follow this simple convention.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-3471534848557654312?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/3471534848557654312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2011/04/i-couldnt-agree-more.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/3471534848557654312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/3471534848557654312'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2011/04/i-couldnt-agree-more.html' title='I couldn&apos;t agree more'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-6018408684364450170</id><published>2011-02-01T19:41:00.000-06:00</published><updated>2011-02-01T19:41:01.156-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vail'/><category scheme='http://www.blogger.com/atom/ns#' term='whs'/><title type='text'>Turns out it is the former</title><content type='html'>As in "We're tidying up in prepartion for the final feature set".&lt;br /&gt;&lt;br /&gt;&lt;a href="http://thenextweb.com/microsoft/2011/02/01/microsoft-has-finished-the-windows-home-server-vail-rc-download-coming-thursday/"&gt;Vail Release Candidate is supposed to be out this week&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-6018408684364450170?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/6018408684364450170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2011/02/turns-out-it-is-former.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/6018408684364450170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/6018408684364450170'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2011/02/turns-out-it-is-former.html' title='Turns out it is the former'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-3708206401487691153</id><published>2011-02-01T17:20:00.000-06:00</published><updated>2011-02-01T17:20:58.926-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vail'/><category scheme='http://www.blogger.com/atom/ns#' term='whs'/><title type='text'>I wonder what's going to happen to Vail</title><content type='html'>I've been running the household media and file storage off of &lt;a href="http://www.microsoft.com/windows/products/winfamily/windowshomeserver/default.mspx"&gt;Windows Home Server&lt;/a&gt; for over a year now and it works great as a centralized file store/media server. &lt;br /&gt;&lt;br /&gt;I've been looking forward to version 2 of WHS, which goes by codename Vail, for quite some time. This is especially true since MS &lt;a href="http://www.liveside.net/2011/01/10/windows-phone-7-comes-to-windows-home-server-codename-vail-and-media-center-set-top-boxes/"&gt;demoed a WP7 app&lt;/a&gt; that can access a WHS server from anywhere on the interwebs at CES. But alas Vail has also been through some trails and tribulations since MS announced &lt;a href="http://www.engadget.com/2010/11/24/windows-home-server-vail-drops-drive-extender-support-ms-sugg/"&gt;they are dropping the drive extender technology&lt;/a&gt; (basically a software managed JBOD raid that allowed you set set up massive and arbitrary storage pools and easily manage them). &lt;br /&gt;&lt;br /&gt;While there are rumors of an impending beta of Vail I am not seeing much out there. Today my one MS Connect product suggestion went from Proposed, to postponed and then to closed. I'm not sure if that means "we're cleaning things up in preparation for defining the final feature set" or "we're cleaning things up because we're closing up shop on this thing".&lt;br /&gt;&lt;br /&gt;I sure hope they don't kill WHS. It is nice and easy to install and manage and most of the other competitors out there for a consumer based "server" slash media system are all linuxy; and my brains just to small for remembering how to configure a linux server, especially if I want my XBox to see it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-3708206401487691153?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/3708206401487691153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2011/02/i-wonder-whats-going-to-happen-to-vail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/3708206401487691153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/3708206401487691153'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2011/02/i-wonder-whats-going-to-happen-to-vail.html' title='I wonder what&apos;s going to happen to Vail'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-7836457225222627772</id><published>2011-01-16T09:49:00.002-06:00</published><updated>2011-01-16T10:58:21.489-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='windows-phone-7'/><title type='text'>GestureBehavior and GestureTrigger</title><content type='html'>The &lt;a href="http://silverlight.codeplex.com/"&gt;Silverlight toolkit&lt;/a&gt; has a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GestureService &lt;/span&gt;and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GestureListener &lt;/span&gt;that allows you to pick up events from gesture input. Oddly enough it doesn't include Xaml types to easily plug those into a page and bind those events to elements and MVVM commands.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_l73vOpwhZrg/TTMP3DLe2II/AAAAAAAAABM/EBM4LlT8cSg/s1600/Capture.PNG" imageanchor="1" style="margin-right:1em; margin-bottom:1em"&gt;&lt;img border="0" height="320" width="194" src="http://4.bp.blogspot.com/_l73vOpwhZrg/TTMP3DLe2II/AAAAAAAAABM/EBM4LlT8cSg/s320/Capture.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Here is an example of using a simple behavior and set of triggers that allow you to do that.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;TextBlock Text="{Binding Welcome}"&amp;gt;&lt;br /&gt;    &amp;lt;i:Interaction.Behaviors&amp;gt;&lt;br /&gt;        &amp;lt;li:GestureBehavior/&amp;gt;&lt;br /&gt;    &amp;lt;/i:Interaction.Behaviors&amp;gt;&lt;br /&gt;    &amp;lt;i:Interaction.Triggers&amp;gt;&lt;br /&gt;        &amp;lt;li:DoubleTapTrigger&amp;gt;&lt;br /&gt;            &amp;lt;cmd:EventToCommand Command="{Binding DoubleTapCommand}" PassEventArgsToCommand="True"/&amp;gt;&lt;br /&gt;        &amp;lt;/li:DoubleTapTrigger&amp;gt;&lt;br /&gt;    &amp;lt;/i:Interaction.Triggers&amp;gt;&lt;br /&gt;&amp;lt;/TextBlock&amp;gt;&lt;/pre&gt;The TextBlock above is bound to a ViewModel that of course has a DoupleTapCommand. In this case a RelayCommand from MVVM Light:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;public MainViewModel()&lt;br /&gt;{&lt;br /&gt;    DoubleTapCommand = new RelayCommand&amp;lt;GestureEventArgs&amp;gt;(e =&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        MessageBox.Show("double tap " + e.OriginalSource.ToString());&lt;br /&gt;    });&lt;br /&gt;&lt;br /&gt;    DragStartedCommand = new RelayCommand&amp;lt;DragStartedGestureEventArgs&amp;gt;(Drag);&lt;br /&gt;    DragDeltaCommand = new RelayCommand&amp;lt;DragDeltaGestureEventArgs&amp;gt;(Drag);&lt;br /&gt;    DragCompletedCommand = new RelayCommand&amp;lt;DragCompletedGestureEventArgs&amp;gt;(Drag);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public RelayCommand&amp;lt;GestureEventArgs&amp;gt; DoubleTapCommand&lt;br /&gt;{&lt;br /&gt;    get;&lt;br /&gt;    private set;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And we can implement a quick and dirty drag and drop:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;Point _start;&lt;br /&gt;private void Drag(DragStartedGestureEventArgs e)&lt;br /&gt;{&lt;br /&gt;    UIElement ui = e.OriginalSource as UIElement;&lt;br /&gt;    if (ui != null)&lt;br /&gt;    {&lt;br /&gt;        if (!(ui.RenderTransform is TranslateTransform))&lt;br /&gt;            ui.RenderTransform = new TranslateTransform();&lt;br /&gt;&lt;br /&gt;        TranslateTransform t = ui.RenderTransform as TranslateTransform;&lt;br /&gt;&lt;br /&gt;        _start = new Point();&lt;br /&gt;        _start.X = t.X;&lt;br /&gt;        _start.Y = t.Y;&lt;br /&gt;&lt;br /&gt;        e.Handled = true;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private void Drag(DragDeltaGestureEventArgs e)&lt;br /&gt;{&lt;br /&gt;    UIElement ui = e.OriginalSource as UIElement;&lt;br /&gt;    if (ui != null)&lt;br /&gt;    {&lt;br /&gt;        TranslateTransform t = ui.RenderTransform as TranslateTransform;&lt;br /&gt;&lt;br /&gt;        t.X += e.HorizontalChange;&lt;br /&gt;        t.Y += e.VerticalChange;&lt;br /&gt;        e.Handled = true;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private void Drag(DragCompletedGestureEventArgs e)&lt;br /&gt;{&lt;br /&gt;    UIElement ui = e.OriginalSource as UIElement;&lt;br /&gt;    if (ui != null &amp;&amp; _start != null)&lt;br /&gt;    {&lt;br /&gt;        if (MessageBox.Show("Press cancel to abort this move.", "Really?", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)&lt;br /&gt;        {&lt;br /&gt;            TranslateTransform t = ui.RenderTransform as TranslateTransform;&lt;br /&gt;&lt;br /&gt;            t.X = _start.X;&lt;br /&gt;            t.Y = _start.Y;&lt;br /&gt;            e.Handled = true;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public RelayCommand&amp;lt;DragStartedGestureEventArgs&amp;gt; DragStartedCommand&lt;br /&gt;{&lt;br /&gt;    get;&lt;br /&gt;    private set;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public RelayCommand&amp;lt;DragDeltaGestureEventArgs&amp;gt; DragDeltaCommand&lt;br /&gt;{&lt;br /&gt;    get;&lt;br /&gt;    private set;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public RelayCommand&amp;lt;DragCompletedGestureEventArgs&amp;gt; DragCompletedCommand&lt;br /&gt;{&lt;br /&gt;    get;&lt;br /&gt;    private set;&lt;br /&gt;}&lt;/pre&gt;Code and example is &lt;a href="http://www.zumodrive.com/share/9QlhYWVhYz"&gt;available here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-7836457225222627772?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/7836457225222627772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2011/01/gesturebehavior-and-gesturetrigger.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/7836457225222627772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/7836457225222627772'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2011/01/gesturebehavior-and-gesturetrigger.html' title='GestureBehavior and GestureTrigger'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_l73vOpwhZrg/TTMP3DLe2II/AAAAAAAAABM/EBM4LlT8cSg/s72-c/Capture.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-9149609246200757943</id><published>2011-01-10T18:46:00.002-06:00</published><updated>2011-01-11T15:52:43.841-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XNA'/><category scheme='http://www.blogger.com/atom/ns#' term='windows-phone-7'/><title type='text'>XNA Here I Come</title><content type='html'>I'm thinking that an animated aquarium would be a fun little project for the Windows Phone so I've decided to port &lt;a href="http://www.codeproject.com/KB/gadgets/FishTank.aspx"&gt;the WinForms version&lt;/a&gt; I did awhile back. After a couple of fruitless hours of trying to wrestle silverlight to do animated images I thought to myself "Wait a minute. This has to be &lt;b&gt;a lot&lt;/b&gt; easier in DirectX".&lt;br /&gt;&lt;br /&gt;Lo and behold &lt;a href="http://www.dreamincode.net/forums/topic/204801-frame-animation-with-xna/"&gt;it is&lt;/a&gt; because of course frame animation is a big part of game programming. Got the first version whipped up in a just a few hours.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-9149609246200757943?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/9149609246200757943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2011/01/xna-here-i-come.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/9149609246200757943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/9149609246200757943'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2011/01/xna-here-i-come.html' title='XNA Here I Come'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-8274115317125999959</id><published>2010-12-26T12:18:00.008-06:00</published><updated>2011-01-16T09:37:04.826-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='windows-phone-7'/><title type='text'>Extend ViewModelLocator to be a bit more dynamic</title><content type='html'>I've been using &lt;a href="http://www.galasoft.ch/mvvm/getstarted/"&gt;MVVM Light&lt;/a&gt; in my Windows Phone development. It's lightweight, has all the base functionality I need and seems pretty solid.&lt;br /&gt;&lt;br /&gt;One pattern that MVVM Light uses is a static ViewModelLocator class that holds all of the main/root view models in the application. You declare it as a data source in the app.xaml:&lt;pre class="brush: xml"&gt;&amp;lt;vm:ViewModelLocator d:isdatasource="True" x:key="Locator"/&amp;gt;&lt;/pre&gt;&lt;br /&gt;Then in the page Xaml you can do:&lt;pre class="brush: xml"&gt;DataContext="{Binding Main, Source={StaticResource Locator}}"&lt;/pre&gt;&lt;br /&gt;This is great when there is basically a 1:1 mapping between the page and the contents of each view model. What it's not so good at is dealing with the situation where you want the same page to bind to multiple view models are structurally equivalent but have different data contents.&lt;br /&gt;&lt;br /&gt;Take for instance an RSS viewer (which coincidentally enough I'm working on at the moment). You might have a feed that represents articles form a website and another feed that is discussion posts from the same website. Each feed is further broken down into topic channels. So if we wanted to display each feed as a page, with each topic as a Pivot Item on that page we could distill the page xaml down to:&lt;pre class="brush: xml"&gt;&amp;lt;controls:Pivot Title="{Binding Name}" &lt;br /&gt;   ItemsSource="{Binding Topics}" &lt;br /&gt;   ItemTemplate="{StaticResource RssTopicTemplate}"/&amp;gt;&lt;/pre&gt;Now if the ViewModel is statically linked to the page (as above) we need to parametrize the ViewModel as the user navigates from articles to discussions and back. It can be made to work but it violates the &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;Single Responsibility Principle&lt;/a&gt; and I just don't like it.&lt;br /&gt;&lt;br /&gt;So rather than parameterizing the ViewModel how about we parametrize the page? Let's declare the linkage between ViewModel in page on the ViewModel. We'll declare an attribute that specifies the linkage and allows a parameter to be passed the page in the form of a query string.&lt;pre class="brush: csharp"&gt;[Page("/RssPage.xaml?vm=ArticlesStatic")]&lt;br /&gt;public class ArticlesViewModel : ViewModelBase&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;[Page("/RssPage.xaml?vm=ForumsStatic")]&lt;br /&gt;public class ForumsViewModel : ViewModelBase&lt;/pre&gt;&lt;br /&gt;In this app the set of navigable items are collections of viewmodels that are displayed in ListBoxes wherein each ViewModel can be selected and navigated to:&lt;pre class="brush: csharp"&gt;public class ContentsViewModel : ViewModelBase&lt;br /&gt;{&lt;br /&gt;   public ObservableCollection&amp;lt;ViewModelBase&amp;gt; Contents &lt;br /&gt;             { get; private set; }&lt;br /&gt;   public RelayCommand&amp;lt;object&amp;gt; SelectViewModel &lt;br /&gt;             { get; private set; }&lt;br /&gt;&lt;br /&gt;   private void Select(object vm)&lt;br /&gt;   {&lt;br /&gt;      if (vm != null)&lt;br /&gt;      {&lt;br /&gt;         var page = vm.GetType().GetAttribute&amp;lt;PageAttribute&amp;gt;();&lt;br /&gt;         Navigate(page.Page);&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;Then we need a wee bit of code in the page codebehind:&lt;pre class="brush: csharp"&gt;protected override void OnNavigatedTo(NavigationEventArgs e)&lt;br /&gt;{&lt;br /&gt;    if (NavigationContext.QueryString.ContainsKey("vm"))&lt;br /&gt;    {&lt;br /&gt;        string key = NavigationContext.QueryString["vm"];&lt;br /&gt;        DataContext = ViewModelLocator.FindViewModel(key);&lt;br /&gt;    }&lt;br /&gt;    base.OnNavigatedTo(e);&lt;br /&gt;}&lt;/pre&gt;where FindViewModel is a method added to the ViewModelLocator that returns the correct ViewModel using reflection:&lt;pre class="brush: csharp"&gt;public static object FindViewModel(string key)&lt;br /&gt;{&lt;br /&gt;    var prop = typeof(ViewModelLocator).GetProperty(key, &lt;br /&gt;              BindingFlags.Public | BindingFlags.Static);&lt;br /&gt;&lt;br /&gt;    return prop.GetValue(null, null);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;I find that moving the linkage between View and ViewModel onto the ViewModel gives us the flexibility to reuse the same UI to display the contents of multiple, structurally equivalent ViewModels, while still maintaining a loose coupling between those two layers.&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-8274115317125999959?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/8274115317125999959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/12/extend-viewmodellocator-to-be-bit-more.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/8274115317125999959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/8274115317125999959'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/12/extend-viewmodellocator-to-be-bit-more.html' title='Extend ViewModelLocator to be a bit more dynamic'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-5695161600325907476</id><published>2010-12-17T21:42:00.002-06:00</published><updated>2010-12-26T22:58:58.190-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='windows-phone-7'/><title type='text'>CPVanity for Windows Phone</title><content type='html'>I always kind of liked &lt;a href="http://www.codeproject.com/KB/dotnet/CPVanity.aspx"&gt;Luc Pattyn's CPVanity app&lt;/a&gt; that lets you check out your code project reputation and keep an eye on article ranking.&lt;br /&gt;&lt;br /&gt;So &lt;a href="http://www.codeproject.com/KB/windows-phone-7/CPVanityWP7.aspx"&gt;here's a WP7 port&lt;/a&gt; of it as a small homage. It's up &lt;a href="http://social.zune.net/redirect?type=phoneApp&amp;amp;id=31e235e4-4408-e011-9264-00237de2db9e"&gt;on the marketplace&lt;/a&gt; too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-5695161600325907476?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/5695161600325907476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/12/cpvanity-for-windows-phone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/5695161600325907476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/5695161600325907476'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/12/cpvanity-for-windows-phone.html' title='CPVanity for Windows Phone'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-1740439177421137455</id><published>2010-12-15T19:31:00.002-06:00</published><updated>2010-12-21T19:34:28.542-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='windows-phone-7'/><title type='text'>Handy Windows Phone 7 resources</title><content type='html'>Now that I've gotten past the "Hello World" stage of WP7 development here are some code and resources that I've found quite helpful:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.galasoft.ch/mvvm/getstarted/"&gt;GalaSoft's MVVM Light&lt;/a&gt; -          for MVVM support (Commands, ViewModel, Mediator etc.). It nice and lightweight and present a good framework on the phone platform&lt;/li&gt;&lt;li&gt;&lt;a href="http://silverlight.codeplex.com/"&gt;The Silverlight for Windows Phone Toolkit&lt;/a&gt; - for some additional controls like the WrapPanel. Plus transitions and other miscellaneous good stuff not included in the SDK&lt;/li&gt;&lt;li&gt;The &lt;a href="http://www.jeff.wilcox.name/2010/12/updated-phone-hyperlink-button/"&gt;PhoneHyperlinkButton &lt;/a&gt;- It handles executing different &lt;a href="http://msdn.microsoft.com/en-us/library/ff769556%28v=vs.92%29.aspx"&gt;Launchers and Choosers&lt;/a&gt; based on the protocol of the link. For instance it starts the &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.webbrowsertask%28v=vs.92%29.aspx"&gt;WebBrowserTask &lt;/a&gt;for non-relative urls, or the &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.phonecalltask%28VS.92%29.aspx"&gt;PhoneCallTask &lt;/a&gt;for "tel:" etc. Really saves a lot of plumbing and makes it quite easy to invoke those thingys.&lt;/li&gt;&lt;li&gt;The &lt;a href="http://blogs.msdn.com/b/ptorr/archive/2010/08/11/updated-tilt-effect.aspx"&gt;TiltEffect &lt;/a&gt;- attaches to all the Buttons you create and makes them have the tilting behavior when they are pressed. Gives your app the same feel as the built in ones.&lt;/li&gt;&lt;li&gt;A good set of &lt;a href="http://www.google.com/search?q=phone+metro+icons&amp;amp;ie=utf-8&amp;amp;oe=utf-8&amp;amp;aq=t&amp;amp;rls=org.mozilla:en-US:official&amp;amp;client=firefox-a"&gt;Metro UI icons&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The &lt;a href="http://code.msdn.microsoft.com/SilverlightMD5"&gt;Silverlight MD5 implementation&lt;/a&gt; - it's not built in and sometimes you just need it.&lt;/li&gt;&lt;li&gt;The&lt;a href="http://msdn.microsoft.com/en-us/library/ff967548%28v=vs.92%29.aspx"&gt; code on this page&lt;/a&gt; for preserving and restoring UI state on pages -&amp;nbsp; definitely helps dealing with page lifecycle and UI transient state.&lt;/li&gt;&lt;li&gt;This &lt;a href="http://msdn.microsoft.com/en-us/library/gg442303%28v=vs.92%29.aspx"&gt;CustomIndeterminateProgressBar &lt;/a&gt;- it moves the animating off of the UI thread and onto the compositor thread so it looks much smoother.&amp;nbsp;&lt;/li&gt;&lt;li&gt;A nice visual summary of the &lt;a href="http://ria.dzone.com/articles/pre-defined-system-styles-and"&gt;pre-defined phone styles&lt;/a&gt;. &lt;/li&gt;&lt;/ul&gt;&lt;a href="http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-1740439177421137455?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/1740439177421137455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/12/handy-windows-phone-7-resources.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/1740439177421137455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/1740439177421137455'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/12/handy-windows-phone-7-resources.html' title='Handy Windows Phone 7 resources'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-4872962041635188066</id><published>2010-12-08T18:28:00.004-06:00</published><updated>2010-12-26T23:00:13.403-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='windows-phone-7'/><title type='text'>A helper class to get the current location on a Windows Phone just once</title><content type='html'>Getting the location on Windows Phone is done via the &lt;a href="http://msdn.microsoft.com/en-us/library/system.device.location.geocoordinatewatcher.aspx"&gt;GeoCoordinateWatcher&lt;/a&gt;. The coordinate watcher has a &lt;a href="http://msdn.microsoft.com/en-us/library/ff431814%28v=VS.92%29.aspx"&gt;some best practices associated with it&lt;/a&gt; one of which is to minimize power consumption. Once you turn this thing on its going to be using the GPS to stream location event back to your app which will hit the battery.&lt;br /&gt;&lt;br /&gt;There are some instance where you may not a running notification of the current potion but just want the current position (for instance you may want to initialize the position on a map but not track changes to position). &lt;br /&gt;&lt;br /&gt;So this is a small helper class that starts up the coordinate watcher asynchronously, returns the first coordinate found and then shuts it down. One could use &lt;a href="http://msdn.microsoft.com/en-us/library/system.device.location.geocoordinatewatcher.trystart.aspx"&gt;TryStart &lt;/a&gt;like so:&lt;br /&gt;&lt;pre  class="brush: csharp"&gt;using (var watcher =  new &lt;br /&gt;                GeoCoordinateWatcher(GeoPositionAccuracy.Default))&lt;br /&gt;{&lt;br /&gt;    var location = watcher.TryStart&lt;br /&gt;                (false, TimeSpan.FromMilliseconds(1000));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;but since that will block your UI thread (assuming you call it from the UI) you'd need to wrap it in some asynchronous stuff anyways.&lt;br /&gt;So I use this class:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;public class ImmediateLocation : IDisposable&lt;br /&gt;{&lt;br /&gt;    private GeoCoordinateWatcher _watcher;&lt;br /&gt;    private Action&amp;lt;GeoCoordinate&amp;gt; _action;&lt;br /&gt;&lt;br /&gt;    public ImmediateLocation(Action&amp;lt;GeoCoordinate&amp;gt; a)&lt;br /&gt;    {&lt;br /&gt;        Debug.Assert(a != null);&lt;br /&gt;&lt;br /&gt;        _action = a;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void GetLocation()&lt;br /&gt;    {&lt;br /&gt;        if (_watcher == null)&lt;br /&gt;        {&lt;br /&gt;            _watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);&lt;br /&gt;            _watcher.MovementThreshold = 1000;&lt;br /&gt;&lt;br /&gt;            _watcher.PositionChanged += new &lt;br /&gt;                EventHandler&amp;lt;GeoPositionChangedEventArgs&amp;lt;GeoCoordinate&amp;gt;&amp;gt;&lt;br /&gt;                (_watcher_PositionChanged);&lt;br /&gt;            _watcher.StatusChanged += new &lt;br /&gt;                EventHandler&amp;lt;GeoPositionStatusChangedEventArgs&amp;gt;&lt;br /&gt;                (_watcher_StatusChanged);&lt;br /&gt;&lt;br /&gt;            _watcher.Start(false);&lt;br /&gt;&lt;br /&gt;            if (_watcher.Status == GeoPositionStatus.Disabled&lt;br /&gt;                || _watcher.Permission == GeoPositionPermission.Denied)&lt;br /&gt;                Dispose();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    void _watcher_StatusChanged(object sender, &lt;br /&gt;        GeoPositionStatusChangedEventArgs e)&lt;br /&gt;    {&lt;br /&gt;        if (e.Status == GeoPositionStatus.Disabled &lt;br /&gt;            || _watcher.Permission == GeoPositionPermission.Denied)&lt;br /&gt;            Dispose();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    void _watcher_PositionChanged(object sender, &lt;br /&gt;        GeoPositionChangedEventArgs&amp;lt;GeoCoordinate&amp;gt; e)&lt;br /&gt;    {&lt;br /&gt;        _action(e.Position.Location);&lt;br /&gt;        Dispose();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void Dispose()&lt;br /&gt;    {&lt;br /&gt;        if (_watcher != null)&lt;br /&gt;        {&lt;br /&gt;            _watcher.Stop();&lt;br /&gt;            _watcher.PositionChanged -= new &lt;br /&gt;                EventHandler&amp;lt;GeoPositionChangedEventArgs&amp;lt;GeoCoordinate&amp;gt;&amp;gt;&lt;br /&gt;                (_watcher_PositionChanged);&lt;br /&gt;            _watcher.StatusChanged -= new &lt;br /&gt;                EventHandler&amp;lt;GeoPositionStatusChangedEventArgs&amp;gt;&lt;br /&gt;                (_watcher_StatusChanged);&lt;br /&gt;            _watcher.Dispose();&lt;br /&gt;        }&lt;br /&gt;        _watcher = null;&lt;br /&gt;        _action = null;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Then you can just do this:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;void InitLocation()&lt;br /&gt;{&lt;br /&gt;     var immediate = new ImmediateLocation(x =&gt; location = x);&lt;br /&gt;     immediate.GetLocation();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;GeoCoordinate location;&lt;/pre&gt;It acts like a one time use, fire and forget location setter that cleans itself up when done. It does have Dispose if you want to mange the lifetime more closely.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-4872962041635188066?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/4872962041635188066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/12/helper-class-to-get-current-location-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/4872962041635188066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/4872962041635188066'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/12/helper-class-to-get-current-location-on.html' title='A helper class to get the current location on a Windows Phone just once'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-4028299065837192655</id><published>2010-12-05T14:50:00.000-06:00</published><updated>2010-12-05T14:50:03.050-06:00</updated><title type='text'>New CodeProject article</title><content type='html'>I just posted &lt;a href="http://www.codeproject.com/KB/windows-phone-7/MyLastFm.aspx"&gt;an article on codeproject&lt;/a&gt; that goes into detail on my experience building a Windows Phone 7 app. Source code included. Check it out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-4028299065837192655?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/4028299065837192655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/12/new-codeproject-article.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/4028299065837192655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/4028299065837192655'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/12/new-codeproject-article.html' title='New CodeProject article'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-2631705103887176852</id><published>2010-12-05T09:31:00.000-06:00</published><updated>2010-12-05T09:31:42.903-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='windows-phone-7'/><title type='text'>Microsoft posts a nice improvement to the WP7 progress bar</title><content type='html'>Showing that your WP7 app is doing some work is as simple as adding a progress bar and setting its IsIndeterminate property to true. This will show the animating dots that glide from left to right in all the WP7 apps.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;ProgressBar IsIndeterminate="{Binding Working}"/&amp;gt;&lt;/pre&gt;&lt;br /&gt;The problem with the current version of the control is that it animates on the UI thread. So if your UI is doing something as well it can be kind of jerky.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/gg442303%28VS.92%29.aspx"&gt;MSDN has a code snippet&lt;/a&gt; that moves the animation to the compositor thread. I'd recommend using this approach as it has a noticeable improvement, animating nice and smoothly.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-2631705103887176852?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/2631705103887176852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/12/microsoft-posts-nice-improvement-to-wp7.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/2631705103887176852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/2631705103887176852'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/12/microsoft-posts-nice-improvement-to-wp7.html' title='Microsoft posts a nice improvement to the WP7 progress bar'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-4194611148746491928</id><published>2010-12-02T07:01:00.000-06:00</published><updated>2010-12-02T07:01:14.437-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='windows-phone-7'/><title type='text'>Got a WP7 app published</title><content type='html'>There's already a Microsoft &lt;a href="http://social.zune.net/redirect?type=phoneApp&amp;id=81bd6dad-66f7-df11-9264-00237de2db9e"&gt;last.fm&lt;/a&gt; browser/player but since I like last.fm and have some experience with their API, I thought it would be a good WP7 learning tool. Plus it goes a little more in dpeth into the content.&lt;br /&gt;&lt;br /&gt;It's &lt;a href="http://social.zune.net/redirect?type=phoneApp&amp;id=81bd6dad-66f7-df11-9264-00237de2db9e"&gt;published now on the app hub&lt;/a&gt;. So that's pretty cool.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-4194611148746491928?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/4194611148746491928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/12/got-wp7-app-published.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/4194611148746491928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/4194611148746491928'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/12/got-wp7-app-published.html' title='Got a WP7 app published'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-5801734601330523947</id><published>2010-11-25T09:28:00.003-06:00</published><updated>2010-12-05T10:33:20.936-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='windows-phone-7'/><title type='text'>Lesson's learned from my first WP7 App submission</title><content type='html'>&lt;b&gt;Lesson 1: Don't forget about the Light theme.&lt;/b&gt;&lt;br /&gt;I developed the app completely using the Dark theme on my phone and the emulator. Lo and behold switch it to Light and some parts of it were unreadable, especially the ApplicationBar. My first submission was rejected because of this. Other parts just didn't all that good on the Light theme. We'll see how swing #2 goes...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lesson 2: Don't set the ApplicationBar colors unless you really want those colors on both themes.&lt;/b&gt;&lt;br /&gt;You can't DataBind them and they will be switched automatically per Theme by WP7, but not if you have set the colors by hand in your XAML.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lesson 3: Don't use color icons on the ApplicationBar&lt;/b&gt;&lt;br /&gt;Again, they may look great on the dark theme but switch to the Light theme and they will be drawn as black outlines at best, black blobs at worst. Use White on Transparent icons. They look fine on both themes. There are some &lt;a href="http://www.mobilitynews.net/?p=11006"&gt;good ones online&lt;/a&gt;. Don't include the outer circle (the app bar adds it) and set the image itself to 24x24.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-5801734601330523947?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/5801734601330523947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/11/lessons-learned-from-my-first-wp7-app.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/5801734601330523947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/5801734601330523947'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/11/lessons-learned-from-my-first-wp7-app.html' title='Lesson&apos;s learned from my first WP7 App submission'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-451217975183806359</id><published>2010-10-13T18:21:00.003-05:00</published><updated>2010-10-15T13:55:48.405-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='windows-phone-7'/><title type='text'>I'm actually getting excited for Windows Phone 7</title><content type='html'>&lt;p$1&gt;I've always been a nerd for mobile devices. I buy new phones more often than is wise; mostly just to see the latest technology. For years I had Windows Mobile based phones and even convinced myself that I liked them. The HTC Touch (WM 6) almost bordered on not sucking, but deep down I knew that&amp;nbsp;Windows Mobile was&amp;nbsp;slow, clunky and had the worst of the two worlds of PDA and Phone. I even had a WM SmartPhone once but don't get me started (I never did buy a SmartWatch though).&lt;br /&gt;&lt;p$1&gt;&lt;p$1&gt;Finally, a year or so ago, after the umpteenth hard-rest to get my Window Mobile device to actually work as a phone again, I gave up and bought a BlackBerry. It's worked but I've never really liked it.&lt;br /&gt;&lt;p$1&gt;&lt;p$1&gt;But now &lt;a href="http://www.microsoft.com/windowsphone/en-us/default.aspx"&gt;Windows Phone 7&lt;/a&gt; has launched. And I gotta say it looks cool. No more Windows 95 trying to be a mobile OS. And it looks interestingly enough different from iOS and Android to have me curious. Plus I have a reasonable chance of being able to jump start some app development without having to learn the Eclipse/Java/Android stack and there's no way in hell I'll have the time to figure out to develop on a Mac with Objective C.&lt;br /&gt;&lt;p$1&gt;&lt;p$1&gt;I've got the SDK and have already whipped up a quick app. Now all I need is a new phone.&lt;br /&gt;&lt;p$1&gt;&lt;p$1&gt;The temptation is killing me. It's probably a foregone conclusion at this point.&lt;/p$1&gt;&lt;/p$1&gt;&lt;/p$1&gt;&lt;/p$1&gt;&lt;/p$1&gt;&lt;/p$1&gt;&lt;/p$1&gt;&lt;/p$1&gt;&lt;/p$1&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-451217975183806359?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/451217975183806359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/10/im-actually-getting-excited-for-windows.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/451217975183806359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/451217975183806359'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/10/im-actually-getting-excited-for-windows.html' title='I&apos;m actually getting excited for Windows Phone 7'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-982694320188395180</id><published>2010-06-13T18:12:00.004-05:00</published><updated>2010-06-17T18:33:12.202-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google-code'/><category scheme='http://www.blogger.com/atom/ns#' term='m4a'/><category scheme='http://www.blogger.com/atom/ns#' term='iTunes'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Reading iTunes m4a tags with .net</title><content type='html'>So it turns out that if you need some code to read media information out of an m4a file the only viable option to be found on the interwebs is a project called &lt;a href="http://atomicparsley.sourceforge.net/"&gt;Atomic Parsley&lt;/a&gt;. Written in C/C++, you can tell a lot of time was put into reverse engineering the structure of MPG-4 audio file meta data and specifically, the types of tags used by iTunes.&lt;br /&gt;&lt;br /&gt;The downside to that set of code is that it is written as a command line utility (global state, lots of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;fprintf&lt;/span&gt;, and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;exit(1)&lt;/span&gt; for error handling) and not at all structured in a way to be easily used as a class or component; especially from managed code.&lt;br /&gt;&lt;br /&gt;Since what I have been looking for is some code that can be used from C#, I took the pieces of Atomic Parsley that I needed and restructured them as C++ classes. From there it wasn't too hard to create a C++/CLI wrapper for easy consumption in C#.&lt;br /&gt;&lt;br /&gt;On the nostalgia side: It has been a long time since I've seen calls to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;malloc&lt;/span&gt; and I even forgot for second that unmanaged memory needs to be manually initialized to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;NULL&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;And on the new technology side: this was a good foray into the latest C++/Cli syntax, using VS.NET 2010 and .NET4. It's getting more and more like C# in flavor but is still feels cumbersome in comparison. That being said, when creating a shiny new managed interface around legacy code, it cannot be beat. &lt;br /&gt;&lt;br /&gt;So if you are looking for a mechanism to read meta-data from iTunes/m4a files the result might be helpful. &lt;a href="http://code.google.com/p/m4sharp/"&gt;Check it out on google code&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-982694320188395180?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/982694320188395180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/06/reading-itunes-m4a-tags-with-net.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/982694320188395180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/982694320188395180'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/06/reading-itunes-m4a-tags-with-net.html' title='Reading iTunes m4a tags with .net'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-3248688076298968026</id><published>2010-04-05T19:03:00.000-05:00</published><updated>2010-04-05T19:03:13.577-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='.net-4'/><category scheme='http://www.blogger.com/atom/ns#' term='alpha-blending'/><title type='text'>A new CodeProject article</title><content type='html'>A while back I came across a &lt;a href="http://www.codeproject.com/KB/GDI-plus/LovelyGoldFishDeskPet.aspx"&gt;fun bit of code on CodeProject&lt;/a&gt; that used alpha blending to animate a fish swimming around on the screen. I've been toying around with that code on and off for awhile and it finally has turned into a whole bunch of fish swimming around on the screen.&lt;br /&gt;&lt;br /&gt;If you've been dieing to have fish swimming around on your screen the wait is over. &lt;a href="http://www.codeproject.com/KB/gadgets/FishTank.aspx"&gt;Check it out over at CodeProject&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;(This is written against the .NET 4 RC. You may need to download &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=8c1e3964-5c6c-440d-91dd-14cc1f42af95&amp;displaylang=en"&gt;this &lt;/a&gt;for it to work.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-3248688076298968026?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/3248688076298968026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/04/new-codeproject-article.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/3248688076298968026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/3248688076298968026'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/04/new-codeproject-article.html' title='A new CodeProject article'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-6199082664632385313</id><published>2010-02-21T12:39:00.002-06:00</published><updated>2010-12-26T23:01:03.178-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Dynamically evaluating a JOIN expression with Linq</title><content type='html'>For the last little while I've been toying around with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;System.Linq.Expressions&lt;/span&gt; and a mini SQL parser to see how far I can go with evaluating plain text SQL expressions against arbitrary collections of objects. It's mostly a side project for my own enjoyment but eventually I am hoping it actually turns into something broadly useful.&lt;br /&gt;&lt;br /&gt;Results so far I've put on CodeProject:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/linq/SqlLinq.aspx"&gt;http://www.codeproject.com/KB/linq/SqlLinq.aspx&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/linq/QueryAnything.aspx"&gt;http://www.codeproject.com/KB/linq/QueryAnything.aspx&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;It's been awhile but today I opened up that code again and got a basic &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;JOIN &lt;/span&gt;operator working. This is cool because ultimately I'd like to be able to join loosely related datasources; say across the mp3 tags in my music collection and the data on my &lt;a href="http://last.fm/"&gt;last.fm&lt;/a&gt; account.&lt;br /&gt;&lt;br /&gt;So just now I've been able to get this unit test to pass:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;[TestMethod]&lt;br /&gt;public void SimpleJoin()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerable source&amp;lt;Person&amp;gt; = TestData.GetPeople();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerable families&amp;lt;Family&amp;gt; = TestData.GetFamilies();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var answer = source.Join(families, p =&amp;gt; p.Address, f =&amp;gt; f.Address,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (p, f) =&amp;gt; new FamilyMember { Name = p.Name, LastName = f.Name, Location = f.Address });&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var result = source.Query&amp;lt;Person, Family, FamilyMember&amp;gt;&lt;br /&gt;              ("SELECT Name, that.Name AS LastName, Address AS Location &lt;br /&gt;              FROM this INNER JOIN that ON this.Address = that.Address", families);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsTrue(result.SequenceEqual(answer));&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;This is cool because now I can start generating complex queries without having compile time knowledge of the underlying data structures. Once I get things fleshed out further I'll update things on CodeProject.&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Membership/View.aspx?mid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-6199082664632385313?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/6199082664632385313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/02/dynamically-evaluating-join-expression.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/6199082664632385313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/6199082664632385313'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/02/dynamically-evaluating-join-expression.html' title='Dynamically evaluating a JOIN expression with Linq'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-1667564567497005032</id><published>2010-02-15T20:32:00.000-06:00</published><updated>2010-02-15T20:32:17.217-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='trace'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>A new CodeProject article</title><content type='html'>I always like&amp;nbsp; to use S&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ystem.Diagnostics.Trace&lt;/span&gt; to report detailed status to the user. For the longest time I used a handy little &lt;b&gt;WinForms &lt;/b&gt;control that inherited from &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;TextBox &lt;/span&gt;to do that. Well now that I am hiking up the &lt;b&gt;WPF &lt;/b&gt;learning curve I need a new version.&lt;br /&gt;&lt;br /&gt;Said version is &lt;a href="http://www.codeproject.com/KB/WPF/WpfTraceDocument.aspx"&gt;posted on Codeproject&lt;/a&gt;. Check it out if you need such a thing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-1667564567497005032?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/1667564567497005032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/02/new-codeproject-article.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/1667564567497005032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/1667564567497005032'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/02/new-codeproject-article.html' title='A new CodeProject article'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-673334382169726136</id><published>2010-02-07T19:29:00.002-06:00</published><updated>2010-02-07T19:34:43.822-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>C# Property class Part 2</title><content type='html'>Commenter &lt;a href="http://www.codeproject.com/script/Membership/View.aspx?mid=69496"&gt;tonyt&lt;/a&gt; (from &lt;a href="http://www.codeproject.com/"&gt;CodeProject&lt;/a&gt;) rightly points out that there are drawbacks to this approach: &lt;a href="http://spookycoding.blogspot.com/2010/01/c-proeprty-class.html"&gt;A C# Property Class&lt;/a&gt;.&lt;br /&gt;&lt;blockquote&gt;Why:&lt;br /&gt;&lt;br /&gt;Because there is a mountain of core functionalty in .NET that relies heavily on things like property access via reflection (like data binding) and via &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;System.ComponentModel &lt;/span&gt;(e.g., &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;TypeDescriptor&lt;/span&gt;), none of which support your take on implementing properties.&lt;br /&gt;&lt;br /&gt;You can implement &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;INotifyPropertyChanged &lt;/span&gt;on any class that offers a more efficient way to get notified about property changes, as it requires only one delegate for each listener, regardless of how many supported properties you have. &lt;/blockquote&gt;&lt;br /&gt;He's right. But I still want to explore this approach. What if we take the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Property &lt;/span&gt;class and have it implement &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;INotifyPropertyChanged&lt;/span&gt;?&lt;br /&gt;&lt;pre&gt;public class Property&amp;lt;T&amp;gt; : INotifyPropertyChanged&lt;br /&gt;{&lt;br /&gt;    protected T _value = default(T);&lt;br /&gt;&lt;br /&gt;    public Property()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Property(T value)&lt;br /&gt;    {&lt;br /&gt;        _value = value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public event EventHandler Changed;&lt;br /&gt;&lt;br /&gt;    public event PropertyChangedEventHandler PropertyChanged;&lt;br /&gt;&lt;br /&gt;    public virtual T Value&lt;br /&gt;    {&lt;br /&gt;        get { return _value; }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            if ((value != null &amp;amp;&amp;amp; !value.Equals(_value)) ||&lt;br /&gt;                (_value != null &amp;amp;&amp;amp; !_value.Equals(value)))&lt;br /&gt;            {&lt;br /&gt;                _value = value;&lt;br /&gt;                OnChanged();                    &lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override string ToString()&lt;br /&gt;    {&lt;br /&gt;        return object.ReferenceEquals(_value, null) ? string.Empty : _value.ToString();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected virtual void OnChanged()&lt;br /&gt;    {&lt;br /&gt;        if (Changed != null)&lt;br /&gt;            Changed(this, EventArgs.Empty);&lt;br /&gt;&lt;br /&gt;        if (PropertyChanged != null)&lt;br /&gt;            PropertyChanged(this, new PropertyChangedEventArgs("Value"));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static implicit operator T(Property&lt;t&gt; property)&lt;br /&gt;    {&lt;br /&gt;        if (property == null)&lt;br /&gt;            return default(T);&lt;br /&gt;&lt;br /&gt;        return property.Value;&lt;br /&gt;    }&lt;br /&gt;}&lt;/t&gt;&lt;/pre&gt;&lt;br /&gt;Now we can create an class like so:&lt;br /&gt;&lt;pre&gt;class ViewModel&lt;br /&gt;{&lt;br /&gt;    public ViewModel()&lt;br /&gt;    {&lt;br /&gt;        Status = new Property&amp;lt;string&amp;gt;("");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Property&amp;lt;string&amp;gt; Status { get; private set; }&lt;br /&gt;}&lt;/pre&gt;&lt;i&gt;Note the switch from a &lt;b&gt;readonly &lt;/b&gt;field to a read-only property. WPF binding requires properties and does not work with fields.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;And then we can bind to that in XAML like so:&lt;br /&gt;&lt;pre&gt;&amp;lt;TextBox Text="{Binding Path=Status.Value}"/&amp;gt;&lt;/pre&gt;(assuming that the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DataContext &lt;/span&gt;of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;TextBox &lt;/span&gt;is a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ViewModel &lt;/span&gt;like the one above.)&lt;br /&gt;&lt;br /&gt;That should go a little way to addressing tonyt's point (mostly because WPF data binding is so robust).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Membership/View.aspx?mid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-673334382169726136?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/673334382169726136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/02/c-property-class-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/673334382169726136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/673334382169726136'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/02/c-property-class-part-2.html' title='C# Property class Part 2'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-7622578405070127683</id><published>2010-02-04T00:31:00.001-06:00</published><updated>2010-02-04T00:36:31.364-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bluetooth'/><category scheme='http://www.blogger.com/atom/ns#' term='yum'/><title type='text'>Why does Bluetooth insist on sucking so badly?</title><content type='html'>Every couple of years since I had the grand vision of owning wireless stereo headphones (which I still do not have), I purchase some bluetooth gadget marginally more complicated than a cell phone earbud in order to see if the technology has ceased to suck. So last week I bought a mini Bluetooth wireless mouse to go along with my new Netbook (yum on the netbook BTW: buy one; buy one right now).&lt;br /&gt;&lt;br /&gt;So I get it home, unpack it and first thing first download the bluetooth drivers. 77 megs. Yes that's right 77 megabytes of driver. Oi oh well. Push forward.&lt;br /&gt;&lt;br /&gt;Awhile and a reboot later up it comes. No findy the bluetooth radio. WTF? Oh wait gotta hotkey that to turn it on. Boink up comes Bluetooth but down goes WIFI. WTF? Hotkey, Hotkey. Bluetooth On; Wifi Off. Bluetooth Off; Wifi Off; Bluetooth off; Wifi On. &lt;br /&gt;&lt;br /&gt;See something missing in that sequence? (this we can blame I suppose on the maker of the netbook but I think that the general suckiness of bluetooth forced it upon them)&lt;br /&gt;&lt;br /&gt;Oh well I think. I'll come back to that later. Let's see if I can get this thing to recognize the mouse. A few pushes to the sync button on the mouse and "Installing new HID hardware..."&lt;br /&gt;&lt;br /&gt;"Yay!" I think "Success!" Until... "Your new hardware installed successfully. Please reboot to complete the installation" Uh-oh. So dutifully I reboot; up comes the bluetooth "Let's find some hardware dialog"; push push push; hotkey hotkey hotkey. Nothing. No mouse. Under no combination of pushing and hotkeying does my netbook believe that there is a wireless mouse a mere centimeter away; crying to be recognized.&lt;br /&gt;&lt;br /&gt;So I take the whole thing; dump it back in the bag and return it for one of the 2.4 GHz wireless jobs with the nano transceiver thingy. Pop that puppy in and and up it comes; no software install; recognizes the mouse with no intervention from me. Boop; 30 seconds; mouse.&lt;br /&gt;&lt;br /&gt;So bluetooth has been around how long now? And it still sucks this bad? This is what happens when a technology tries to be all things to all people. I'm sure the designers of blueooth saw/see it as the last wireless technology stack ever needed. By anyone. Anywhere.&lt;br /&gt;&lt;br /&gt;In truth it's a darn fine wireless earbud solution for your cell phone. That's about it. Perhaps I'll check back in a couple of years. In the meantime, nano-transceiver... yum.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-7622578405070127683?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/7622578405070127683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/02/why-does-bluetooth-insist-on-sucky-so.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/7622578405070127683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/7622578405070127683'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/02/why-does-bluetooth-insist-on-sucky-so.html' title='Why does Bluetooth insist on sucking so badly?'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4984249252218519917.post-8379935773521972223</id><published>2010-01-30T09:50:00.010-06:00</published><updated>2010-01-30T20:48:36.632-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CodeProject'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>A C# Property class</title><content type='html'>Soon after starting work in C# there were a couple of code patterns that  arose that made me miss the good ol' C/C++ pre-processor. One of these is the basic pattern of a class property with change notification.&lt;br /&gt;&lt;br /&gt;You've got a class and you want the state of its properties to be observable via events. How  many time have you written the following bit of code in some for or other? &lt;br /&gt;&lt;pre&gt;&lt;span class="code-keyword"&gt;int&lt;/span&gt; _age;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;event&lt;/span&gt; EventHandler AgeChanged;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;protected&lt;/span&gt; &lt;span class="code-keyword"&gt;virtual&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; OnAgeChanged()&lt;br /&gt;{&lt;br /&gt;&lt;span class="code-keyword"&gt;  if&lt;/span&gt;(Changed != &lt;span class="code-keyword"&gt;null&lt;/span&gt;)&lt;br /&gt;    Changed(&lt;span class="code-keyword"&gt;this&lt;/span&gt;, EventArgs.Empty);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;int&lt;/span&gt; Age&lt;br /&gt;{&lt;br /&gt;&lt;span class="code-keyword"&gt;  get&lt;/span&gt;{ &lt;span class="code-keyword"&gt;return&lt;/span&gt; _age; }&lt;br /&gt;&lt;span class="code-keyword"&gt;  set&lt;/span&gt;&lt;br /&gt;  {&lt;br /&gt;&lt;span class="code-keyword"&gt;    if&lt;/span&gt;(value != age)&lt;br /&gt;    {&lt;br /&gt;      value = age;&lt;br /&gt;      OnAgeChanged();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;Automatic properties help when you don't need notification, &lt;span style="font-family: courier new; font-weight: bold;"&gt; INotifyPropertyChange &lt;/span&gt;abstracts that event a little. Still, a lot of  boilerplate. Having  written a fair amount of &lt;b&gt;MFC &lt;/b&gt;in the years prior I really wanted  to be able to do something like:&lt;br /&gt;&lt;pre&gt;DECLARE_PROPERTY(Age, &lt;span class="code-keyword"&gt;int&lt;/span&gt;)&lt;/pre&gt;and  have a fancy macro that would handle the boiler plate. Alas there is no  macro pre-processor in C#-land.&lt;br /&gt;&lt;br /&gt;The introduction of .NET generics  opens up the opportunity to model a class property as a class itself,  while retaining type safety and the same assignment semantics as  intrinsic types. So this little class (and a derived class with a  cancellable event) has become a handy part of my toolbox.&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;class&lt;/span&gt; Property&amp;lt;T&amp;gt;&lt;br /&gt;{&lt;br /&gt;&lt;span class="code-keyword"&gt;  protected&lt;/span&gt; T _value = &lt;span class="code-keyword"&gt;default&lt;/span&gt;(T);&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;  public&lt;/span&gt; Property()&lt;br /&gt;  {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;  public&lt;/span&gt; Property(T value)&lt;br /&gt;  {&lt;br /&gt;    _value = value;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;  public&lt;/span&gt; &lt;span class="code-keyword"&gt;event&lt;/span&gt; EventHandler Changed;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;  public&lt;/span&gt; &lt;span class="code-keyword"&gt;virtual&lt;/span&gt; T Value&lt;br /&gt;  {&lt;br /&gt;&lt;span class="code-keyword"&gt;    get&lt;/span&gt; { &lt;span class="code-keyword"&gt;return&lt;/span&gt; _value; }&lt;br /&gt;&lt;span class="code-keyword"&gt;    set&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;&lt;span class="code-keyword"&gt;       if&lt;/span&gt; ((value != &lt;span class="code-keyword"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !value.Equals(_value)) ||&lt;br /&gt;          (_value != &lt;span class="code-keyword"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !_value.Equals(value)))&lt;br /&gt;       {&lt;br /&gt;          _value = value;&lt;br /&gt;          OnChanged();&lt;br /&gt;       }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;  protected&lt;/span&gt; &lt;span class="code-keyword"&gt;virtual&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; OnChanged()&lt;br /&gt;  {&lt;br /&gt;&lt;span class="code-keyword"&gt;     if&lt;/span&gt; (Changed != &lt;span class="code-keyword"&gt;null&lt;/span&gt;)&lt;br /&gt;       Changed(&lt;span class="code-keyword"&gt;this&lt;/span&gt;, EventArgs.Empty);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;  public&lt;/span&gt; &lt;span class="code-keyword"&gt;static&lt;/span&gt; &lt;span class="code-keyword"&gt;implicit&lt;/span&gt; &lt;span class="code-keyword"&gt;operator&lt;/span&gt; T(Property&lt;t&gt; property)&lt;br /&gt;  {&lt;br /&gt;&lt;span class="code-keyword"&gt;    if&lt;/span&gt; (property == &lt;span class="code-keyword"&gt;null&lt;/span&gt;)&lt;br /&gt;&lt;span class="code-keyword"&gt;      return&lt;/span&gt; &lt;span class="code-keyword"&gt;default&lt;/span&gt;(T);&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;    return&lt;/span&gt; property.Value;&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;using  it is just a matter of declaring a public field on a class declaration.&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;class&lt;/span&gt; Person&lt;br /&gt;{&lt;br /&gt;  &lt;span class="code-keyword"&gt;public&lt;/span&gt; readonly Property&amp;lt;int&amp;gt; Age = &lt;span class="code-keyword"&gt;new&lt;/span&gt; Property&amp;lt;int&amp;gt;();&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;  public&lt;/span&gt; readonly Property&amp;lt;string&amp;gt; Name = &lt;span class="code-keyword"&gt;new&lt;/span&gt; Property&amp;lt;string&amp;gt;();&lt;br /&gt;}&lt;/pre&gt;Interacting  with the properties looks a lot like an intrinsic: &lt;br /&gt;&lt;pre lang="cs"&gt;Person don = &lt;span class="code-keyword"&gt;new&lt;/span&gt; Person();&lt;br /&gt;don.Name.Value = &lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Don"&lt;/span&gt;;&lt;br /&gt;don.Age.Value = &lt;span class="code-digit"&gt;41&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;if&lt;/span&gt; (don.Age &amp;gt; &lt;span class="code-digit"&gt;40&lt;/span&gt;)&lt;br /&gt;  Console.WriteLine(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Ooooooold"&lt;/span&gt;);&lt;/pre&gt;&lt;pre lang="cs"&gt;&amp;nbsp;&lt;/pre&gt;with  the difference that every property now comes with a built in &lt;span style="font-family: courier new;"&gt;Changed  &lt;/span&gt;event&lt;br /&gt;&lt;pre lang="cs"&gt;don.Age.Changed += &lt;span class="code-keyword"&gt;new&lt;/span&gt; EventHandler(Age_Changed);&lt;/pre&gt;&lt;br /&gt;So  anyway, I've found this to be a handy helper class and thought perhaps you  might as well.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;PS: the cancellable derived class looks like this:&lt;/span&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;class&lt;/span&gt; CancellableProperty&amp;lt;T&amp;gt; : Property&amp;lt;T&amp;gt;&lt;br /&gt;{&lt;br /&gt;&lt;span class="code-keyword"&gt;  public&lt;/span&gt; CancellableProperty(T value)&lt;br /&gt;    : &lt;span class="code-keyword"&gt;base&lt;/span&gt;(value)&lt;br /&gt;  {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;  public&lt;/span&gt; &lt;span class="code-keyword"&gt;event&lt;/span&gt; CancelEventHandler Changing;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;  public&lt;/span&gt; &lt;span class="code-keyword"&gt;override&lt;/span&gt; T Value&lt;br /&gt;  {&lt;br /&gt;&lt;span class="code-keyword"&gt;    set&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;&lt;span class="code-keyword"&gt;      if&lt;/span&gt; ((value != &lt;span class="code-keyword"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !value.Equals(_value)) ||&lt;br /&gt;         (_value != &lt;span class="code-keyword"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !_value.Equals(value)))&lt;br /&gt;      {&lt;br /&gt;        CancelEventArgs args = &lt;span class="code-keyword"&gt;new&lt;/span&gt; CancelEventArgs(&lt;span class="code-keyword"&gt;false&lt;/span&gt;);&lt;br /&gt;        OnChanging(args);&lt;br /&gt;&lt;span class="code-keyword"&gt;        if&lt;/span&gt; (args.Cancel == &lt;span class="code-keyword"&gt;false&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;          _value = value;&lt;br /&gt;          OnChanged();&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;  protected&lt;/span&gt; &lt;span class="code-keyword"&gt;virtual&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; OnChanging(CancelEventArgs args)&lt;br /&gt;  {&lt;br /&gt;&lt;span class="code-keyword"&gt;    if&lt;/span&gt; (Changing != &lt;span class="code-keyword"&gt;null&lt;/span&gt;)&lt;br /&gt;      Changing(&lt;span class="code-keyword"&gt;this&lt;/span&gt;, args);&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Membership/View.aspx?mid=122954" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4984249252218519917-8379935773521972223?l=spookycoding.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spookycoding.blogspot.com/feeds/8379935773521972223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spookycoding.blogspot.com/2010/01/c-proeprty-class.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/8379935773521972223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4984249252218519917/posts/default/8379935773521972223'/><link rel='alternate' type='text/html' href='http://spookycoding.blogspot.com/2010/01/c-proeprty-class.html' title='A C# Property class'/><author><name>Don Kackman</name><uri>https://profiles.google.com/108515301253344939265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
