Thursday, April 21, 2011

Five Minute Silverlight 5 Aides-Memoire #4 – Mouse Click Count

Rainbow Rectangle
  1. <Rectangle Width="154"
  2.            Height="77"
  3.            MouseLeftButtonDown="RectangleMouseLeftButtonDown">
  4.     <Rectangle.Fill>
  5.         <LinearGradientBrush x:Name="GradientFill" StartPoint="0,0" EndPoint="1,1">
  6.             <GradientStop Offset="0" Color="Red" />
  7.             <GradientStop Offset="0.1667" Color="Orange" />
  8.             <GradientStop Offset="0.334" Color="Yellow" />
  9.             <GradientStop Offset="0.5001" Color="Green" />
  10.             <GradientStop Offset="0.6668" Color="Blue" />
  11.             <GradientStop Offset="0.8335" Color="Indigo" />
  12.             <GradientStop Offset="1" Color="Violet" />
  13.         </LinearGradientBrush>
  14.     </Rectangle.Fill>
  15. </Rectangle>
  16. <TextBlock x:Name="ClickCountTextBlock"
  17.            Foreground="White"
  18.            HorizontalAlignment="Center"
  19.            VerticalAlignment="Center"
  20.            FontSize="40"
  21.            Opacity="0.4"
  22.            Text="" />

Click Count in MouseEventArgs
  1. private void RectangleMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  2. {
  3.     this.ClickCountTextBlock.Text = e.ClickCount.ToString();
  4.     var topLeft = new Point(0, 0);
  5.     var topRight = new Point(1, 0);
  6.     var bottomLeft = new Point(0, 1);
  7.     var bottomRight = new Point(1, 1);
  8.  
  9.     switch (e.ClickCount)
  10.     {
  11.         case 2:
  12.             this.GradientFill.StartPoint = topRight;
  13.             this.GradientFill.EndPoint = bottomLeft;
  14.             break;
  15.         case 3:
  16.             this.GradientFill.StartPoint = bottomRight;
  17.             this.GradientFill.EndPoint = topLeft;
  18.             break;
  19.         case 4:
  20.             this.GradientFill.StartPoint = bottomLeft;
  21.             this.GradientFill.EndPoint = topRight;
  22.             break;
  23.         default:
  24.             this.GradientFill.StartPoint = topLeft;
  25.             this.GradientFill.EndPoint = bottomRight;
  26.             break;
  27.     }
  28. }

DoubleTripleClick

Five Minute Silverlight 5 Aides-Memoire #3 – Out-of-Browser Native Windows

Native Window creation in code
  1. private void ButtonClick(object sender, RoutedEventArgs e)
  2. {
  3.     if (!Application.Current.IsRunningOutOfBrowser)
  4.     {
  5.         return;
  6.     }
  7.  
  8.     var newGrid = new Grid
  9.     {
  10.         Background = new SolidColorBrush(Colors.White),
  11.         HorizontalAlignment = HorizontalAlignment.Stretch,
  12.         VerticalAlignment = VerticalAlignment.Stretch
  13.     };
  14.  
  15.     var newTextBlock = new TextBlock
  16.     {
  17.         HorizontalAlignment = HorizontalAlignment.Center,
  18.         VerticalAlignment = VerticalAlignment.Center,
  19.         Text = "New TextBlock in a new Window..."
  20.     };
  21.  
  22.     newGrid.Children.Add(newTextBlock);
  23.  
  24.     new Window { Content = newGrid, Visibility = Visibility.Visible, Width = 300, Height = 300 };
  25. }

NativeWindows

Wednesday, April 20, 2011

Five Minute Silverlight 5 Aides-Memoire #2 – Implicit DataTemplates

Data Classes
  1. /// <summary>
  2. /// The cartoon character.
  3. /// </summary>
  4. public class CartoonCharacter
  5. {
  6.     /// <summary>
  7.     /// Gets or sets the forename.
  8.     /// </summary>
  9.     /// <value>The forename.</value>
  10.     public string Forename { get; set; }
  11. }
  12.  
  13. /// <summary>
  14. /// The flintstone.
  15. /// </summary>
  16. public class Flintstone : CartoonCharacter { }
  17.  
  18. /// <summary>
  19. /// The griffin.
  20. /// </summary>
  21. public class Griffin : CartoonCharacter { }
  22.  
  23. /// <summary>
  24. /// The simpson.
  25. /// </summary>
  26. public class Simpson : CartoonCharacter { }

 

XAML
  1. <Grid x:Name="LayoutRoot"
  2.       Background="White">
  3.     <Grid.Resources>
  4.         <Style x:Key="SimpsonStyle"
  5.                TargetType="TextBlock">
  6.             <Setter Property="FontFamily" Value="Comic Sans MS" />
  7.             <Setter Property="FontSize" Value="16" />
  8.             <Setter Property="Foreground" Value="Blue" />
  9.             <Setter Property="FontStyle" Value="Italic" />
  10.         </Style>
  11.         <DataTemplate DataType="this:Simpson">
  12.             <Border Background="Yellow">
  13.                 <StackPanel Orientation="Horizontal">
  14.                     <TextBlock Style="{StaticResource SimpsonStyle}"
  15.                                Text="{Binding Forename}" />
  16.                     <TextBlock Margin="5,0,0,0"
  17.                                Style="{StaticResource SimpsonStyle}"
  18.                                Text="Simpson" />
  19.                 </StackPanel>
  20.             </Border>
  21.         </DataTemplate>
  22.         <DataTemplate DataType="this:Flintstone">
  23.             <Border Background="Orange">
  24.                 <Border.RenderTransform>
  25.                     <TransformGroup>
  26.                         <SkewTransform AngleX="-20" />
  27.                         <ScaleTransform ScaleX="2"
  28.                                         ScaleY="0.75" />
  29.                         <TranslateTransform X="30" />
  30.                     </TransformGroup>
  31.                 </Border.RenderTransform>
  32.                 <StackPanel Orientation="Horizontal">
  33.                     <TextBlock Text="{Binding Forename}" />
  34.                     <TextBlock Margin="5,0,0,0"
  35.                                Text="Flintstone" />
  36.                 </StackPanel>
  37.             </Border>
  38.         </DataTemplate>
  39.         <DataTemplate DataType="this:Griffin">
  40.             <Border BorderBrush="DarkSlateBlue" BorderThickness="2">
  41.                 <StackPanel Orientation="Horizontal">
  42.                     <TextBlock Text="{Binding Forename}" FontSize="18">
  43.                         <TextBlock.Effect>
  44.                             <BlurEffect />
  45.                         </TextBlock.Effect>
  46.                     </TextBlock>
  47.                     <TextBlock Margin="5,0,0,0"
  48.                                FontSize="22" CharacterSpacing="5"
  49.                                Text="Griffin">
  50.                         <TextBlock.Effect>
  51.                             <DropShadowEffect />
  52.                         </TextBlock.Effect>
  53.                     </TextBlock>
  54.                 </StackPanel>
  55.             </Border>
  56.         </DataTemplate>
  57.     </Grid.Resources>
  58.     <ListBox x:Name="CartoonCharactersListBox"
  59.              Margin="50,20"
  60.              BorderBrush="Blue"
  61.              BorderThickness="2"
  62.              ItemsSource="{Binding}" />
  63. </Grid>

 

SL5AM2

Yeugh!!

Five Minute Silverlight 5 Aides-Memoire #1 – Style Setter Binding

Code Snippet
  1. <Grid x:Name="LayoutRoot"
  2.       Background="White">
  3.     <Grid.RowDefinitions>
  4.         <RowDefinition />
  5.         <RowDefinition Height="Auto" />
  6.     </Grid.RowDefinitions>
  7.     <Grid.Resources>
  8.         <Style x:Key="VariableFontTextBlockStyle"
  9.                TargetType="TextBlock">
  10.             <Setter Property="Foreground" Value="DarkOrange" />
  11.             <Setter Property="FontWeight" Value="Bold" />
  12.             <Setter Property="FontSize" Value="{Binding ElementName=FontSizeSlider, Path=Value}" />
  13.         </Style>
  14.     </Grid.Resources>
  15.     <TextBlock x:Name="SampleTextBlock"
  16.                Grid.Row="0"
  17.                HorizontalAlignment="Center"
  18.                VerticalAlignment="Center"
  19.                Style="{StaticResource VariableFontTextBlockStyle}"
  20.                Text="No Mr Bond - I expect you to die" />
  21.     <Slider x:Name="FontSizeSlider"
  22.             Grid.Row="1"
  23.             MaxWidth="500"
  24.             Margin="100,30"
  25.             Maximum="64"
  26.             Minimum="8"
  27.             Value="12" />
  28. </Grid>

SL5AM1

Friday, April 15, 2011

Building Silverlight Chord Factory: Part 3 – The View and Windows Phone 7

Despite my good intentions, it’s been a year since I posted the second part of my set of posts on Building Silverlight Chord Factory (see Part 1 and Part 2). The third part – on the View in the Model-View-ViewModel (MVVM) triptych has been a bit delayed, mainly by work and other pressures, but also by my attention being diverted by the arrival of Windows Phone 7 (WP7).

My practice of exploring new development platforms and languages by converting my hobby project – the Openfeature Chord Factory – kicked in and the application got yet another transformation. Which worked out quite well as it illustrated some of the power and benefits of the MVVM pattern. Converting the Silverlight Chord Factory code to WP7 Silverlight code was pretty simple and the main area of change – the View – was nicely isolated from the remaining code allowing the XAML markup to be adapted to the WP7 Control Toolkit easily and the custom controls in the app to work with virtually no modifications for the new platform.

So now this belated post can be both a look at the original View and at the adaptions involved in moving the app to the WP7 platform.

Here are a few screenshots of the Silverlight application in a couple of incarnations, running in a browser:

SilverlightChordFactory

Note the unfinished musical stave controls…

OpenfeatureChordFactory

Screenshots of Silverlight ChordFactory application

And here are screenshots of the Wp7 application:

WP7ChordFactory

WP7ChordFactorySettings

sWP7ChordFactoryOptions

Screenshots of WP7 app

Leaving aside my relative lack of UI/UX design capability, you can see that basically the User Experience is the same for both versions of the ChordFactory app. And in some of the UI itself the styling is exactly the same – the keyboard keys for example.

In fact I was able to reuse large chunks of the Openfeature Silverlight music controls (Keyboard, Octave and PianoKey controls) that I developed for the browser app because they consist of generic, compatible XAML markup and C# code. The Views in either case are of course nothing more than the markup/styling with bindings to the appropriate data sources in the ViewModel.  With the Model and ViewModel classes being completely platform independent, they needed no redevelopment at all.

So I was able to get the WP7 ChordFactory app up and running in not much more than an easy afternoon of working on it. The majority of the work required lay in adding XNA code to play piano note samples added to the app so that the user can hear the selected chord or scale. Something I couldn’t do as easily with the browser version and hadn’t got around to implementing with MediaElements. Registering with the App Hub and submitting the app took a few trips back and forth to cross all the ‘Ts’ and dot all the ‘Is’, but the app is now live here:

ZuneDownload

Openfeature ChordFactory