Skip to main content

A board game in MVVM Part 5 - Additional Enhancement and Source

This is a continuation of my experience creating a quick board game in silverlight 5
Original Post
Part 1 - The Model
Part 2 - The AI
Part 3 - The View
Part 3b - Commands and Converters
Part 4 - The ViewModel
Play the Game

This is my final post in the series regarding viking. This is the unveiling of the final source code, fully commented along with a few extra enhancements that I've made to it.

One of the things I felt it really needed was some form of additional animation to indicate better what move was just made instead of pieces simply appearing/disappearing. What I did was to use an attached behavior. Behaviors and Attached Properties are extremely useful when it comes to trying to keep to MVVM. It not only keeps that extra code out of your UserControl's code-behind, but also allows the functionality to be reused.

In the way I've used the behavior it utilizes the System.Windows.Interactivity namespace.

  1. xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

I then attached the behavior to the border that controls a piece's visibility. You can note 2 things from this:

  • A new converter - very self-explanatory and you can see it when I post the final source
  • I additionally had to bind the player color differently to instead match the most recent occupant's color since upon hiding a piece it has no occupant.

  1. <Border>
  2.     <interactivity:Interaction.Behaviors>
  3.         <library:FadeBehavior IsVisible="{Binding Occupant, Converter={StaticResource IsNotNullConverter}}" />
  4.     </interactivity:Interaction.Behaviors>
  5.     <Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Command="{Binding DataContext.ActivatePieceCommand, RelativeSource={RelativeSource AncestorType=local:MainPage}}" CommandParameter="{Binding Occupant}" IsEnabled="{Binding Occupant.IsMoveable, FallbackValue=False}">
  6.         <Button.Template>
  7.             <ControlTemplate>
  8.                 <Ellipse HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="{Binding Occupant, Converter={StaticResource KingStrokeConverter}}" StrokeThickness="{Binding Occupant, Converter={StaticResource KingStrokeConverter}}" Fill="{Binding FormerOccupantPlayer, Converter={StaticResource PlayerColorConverter}}">
  9.                     <Ellipse.Effect>
  10.                         <DropShadowEffect Opacity=".5" ShadowDepth="3" />
  11.                     </Ellipse.Effect>
  12.                 </Ellipse>
  13.             </ControlTemplate>
  14.         </Button.Template>
  15.     </Button>
  16. </Border>

This attaches my behavior to the Border and gives me an "OnAttached" and "OnDetaching" events for cleanup. Here's the behavior itself:

  1.     using System;
  2.     using System.Windows;
  3.     using System.Windows.Interactivity;
  4.     using System.Windows.Media.Animation;
  6.     public class FadeBehavior : Behavior<UIElement>
  7.     {
  8.         public static readonly DependencyProperty IsVisibleProperty =
  9.             DependencyProperty.Register("IsVisible", typeof(bool), typeof(FadeBehavior), new PropertyMetadata(false, (s, a) => { ((FadeBehavior)s).OnIsVisibleChanged(a); }));
  11.         private Storyboard fade;
  13.         DoubleAnimation fadeAnimation;
  15.         public bool IsVisible
  16.         {
  17.             get { return (bool)GetValue(IsVisibleProperty); }
  18.             set { SetValue(IsVisibleProperty, value); }
  19.         }
  21.         protected override void OnAttached()
  22.         {
  23.             base.OnAttached();
  25.             AssociatedObject.Opacity = IsVisible ? 1 : 0;
  26.             fade = new Storyboard();
  27.             fadeAnimation = new DoubleAnimation();
  28.             fade.Children.Add(fadeAnimation);
  29.             fadeAnimation.From = AssociatedObject.Opacity;
  30.             fadeAnimation.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 500));
  31.             Storyboard.SetTarget(fadeAnimation, AssociatedObject);
  32.             Storyboard.SetTargetProperty(fadeAnimation, new PropertyPath("Opacity"));
  33.         }
  35.         protected override void OnDetaching()
  36.         {
  37.             base.OnDetaching();
  38.         }
  40.         private void OnIsVisibleChanged(DependencyPropertyChangedEventArgs args)
  41.         {
  42.             if (args.NewValue != null)
  43.             {
  44.                 fadeAnimation.From = AssociatedObject.Opacity;
  45.                 fadeAnimation.To = (bool)args.NewValue ? 1 : 0;
  46.                 fade.Begin();
  47.             }
  48.         }
  49.     }

This means that this behavior can be attached to any UIElement the way I attached it above. It gives me the ability to bind it to any bool to dictate whether it needs to hide or show. With a little further work the duration of the animation should also be configurable but I'll leave that as an excercise to you.

Finally attached you'll find the final source to the project Viking along with some extra time taken for full comments. You can find the source below.

Viking.zip334.49 KB


Thank you for sharing the

Thank you for sharing the final attachments,Additional Enhancement and Source was the last of it to get done on for my assignment,I will always look forward to learn more from you.

Thank you for sharing the

Thank you for sharing the article,The project Viking along with the article spinning looks so great,Keep on sharing more of such incredible article with us that would be great with additional Enhancement and Source


I love the blog. Great post. It is very true, people must learn how to learn before they can learn. lol i know it sounds funny but its very true. . .


Hi I found your site by mistake when i was searching yahoo for this acne issue, I must say your site is really helpful I also love the design, its amazing!. I don’t have the time at the moment to fully read your site but I have bookmarked it and also add your RSS feeds. I will be back in a day or two. thanks for a great site.

I definitely enjoying every

I definitely enjoying every little bit of it. It is a great website and nice share. I want to thank you. Good job! You guys do a great blog, and have some great contents. Keep up the good work.
temple run game


I definitely enjoying every little bit of it. It is a great website and nice share. I want to thank you. Good job! You guys do a great blog, and have some great contents. Keep up the good work.
dry mix concrete plant


I was very pleased to find this site.I wanted to thank you for this great read!! I definitely enjoying every little bit of it and I have you bookmarked to check out new stuff you post.
ibm 8203

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <asp>, <c>, <cpp>, <cs>, <css>, <drupal5>, <drupal6>, <html4strict>, <java>, <javascript>, <jquery>, <php>, <python>, <ruby>, <sql>, <xml>. The supported tag styles are: <foo>, [foo]. PHP source code can also be enclosed in <?php ... ?> or <% ... %>.

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.