Visual Studio 2010 Custom Silverlight Control as Print Template
Simple printing would be a misnomer, perhaps. Printing is the most obvious shortcoming of Microsoft’s Lightswitch development environment. Before we lament about the lack of printing support, let us review what is available. Silverlight has made advances in printing that will allow limited printing. To see a discussion of shortfalls and alternatives see here:
http://stackoverflow.com/questions/4942990/creating-reports-in-silverlight-either-as-pdf-or-send-it-off-to-a-printer
Following with Beth Massi’s Using Word in Lightswitch project from my last post. Simply adding a Silverlight Class Library with a UserControl allows us to add a reference to our LightSwitch project. I have then added the custom control to the bottom of the Customer Detail screen. This is done by adding another Customer Row Layout and setting the control to our custom control. The control will act as a printing template for simple direct printing of the Customer details. I have also added a screen property just to demonstrate that any screen data is available to print via the custom control binding.

By adding to the CustomerDetail screen code CustomerDetail.cs:
partial void CustomerDetail_Activated()
{
this.FindControl("Customer").ControlAvailable
+= new EventHandler<ControlAvailableEventArgs>(CustomerDetail_ControlAvailable);
}
void CustomerDetail_ControlAvailable(object sender, ControlAvailableEventArgs e)
{
SilverlightClassLibrary1.SilverlightControl1 ctrl
= e.Control as SilverlightClassLibrary1.SilverlightControl1;
ctrl.Visibility = System.Windows.Visibility.Collapsed;
}
The custom control will not initially be visible on the screen. We have added a Print Direct button the the screen with the execution code:
System.Windows.Printing.PrintDocument pd = new System.Windows.Printing.PrintDocument();
System.Windows.UIElement ele;
partial void PrintDirect_Execute()
{
this.FindControl("Customer").ControlAvailable
+= webControlAvailable;
pd.PrintPage
+= new EventHandler<System.Windows.Printing.PrintPageEventArgs>(pd_PrintPage);
}
private void webControlAvailable(object sender, ControlAvailableEventArgs e)
{
SilverlightClassLibrary1.SilverlightControl1 ctrl
= e.Control as SilverlightClassLibrary1.SilverlightControl1;
ctrl.Visibility = System.Windows.Visibility.Visible;
ele = ctrl;
pd.Print("name");
ctrl.Visibility = System.Windows.Visibility.Collapsed;
}
private void pd_PrintPage(object sender, System.Windows.Printing.PrintPageEventArgs ev)
{
ev.PageVisual = ele;
}
When the Print Direct button is executed the custom control becomes visible and it is placed as the PageVisual of a silverlight PrintDocument. The document is printed and then our custom control is again collapsed.


This method will allow printing of un-saved screen data on special forms like Invoices, Purchase Orders or Checks. The custom control is set up like this:
<UserControl x:Class="SilverlightClassLibrary1.SilverlightControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="200" d:DesignWidth="300">
<Border BorderThickness="3" BorderBrush="Black" CornerRadius="10" Padding="2">
<StackPanel x:Name="LayoutRoot" Background="White" Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock1" VerticalAlignment="Top" Width="Auto" Text="{Binding Mode=TwoWay, Path=Screen.Customer.FirstName}" FontSize="14" />
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock2" VerticalAlignment="Top" Width="Auto" Text=" " FontSize="14" />
<TextBlock Height="23" HorizontalAlignment="Right" Name="textblock3" VerticalAlignment="Top" Width="Auto" Text="{Binding Mode=TwoWay, Path=Screen.Customer.LastName}" FontSize="14" />
</StackPanel>
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock4" VerticalAlignment="Top" Width="120" Text="{Binding Mode=TwoWay, Path=Screen.Customer.Address1}" FontSize="14" />
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock5" VerticalAlignment="Top" Width="120" Text="{Binding Mode=TwoWay, Path=Screen.Customer.Address2}" FontSize="14" />
<StackPanel Orientation="Horizontal">
<TextBlock Height="23" HorizontalAlignment="Left" Name="textlbock6" VerticalAlignment="Top" Text="{Binding Mode=TwoWay, Path=Screen.Customer.City}" FontSize="14" />
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock7" VerticalAlignment="Top" Width="Auto" Text=", " FontSize="14" />
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock8" VerticalAlignment="Top" Text="{Binding Mode=TwoWay, Path=Screen.Customer.State}" FontSize="14" />
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock9" VerticalAlignment="Top" Text=" " FontSize="14" />
<TextBlock Height="23" HorizontalAlignment="Left" Name="textbock10" VerticalAlignment="Top" Width="Auto" Text="{Binding Mode=TwoWay, Path=Screen.Customer.PostalCode}" FontSize="14" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock11" VerticalAlignment="Top" Width="Auto" Text="Phone: "></TextBlock>
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock12" VerticalAlignment="Top" Width="Auto" Text="{Binding Mode=TwoWay, Path=Screen.Customer.Phone}" FontSize="14" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock13" VerticalAlignment="Top" Width="Auto" Text="Gender: "></TextBlock>
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock14" VerticalAlignment="Top" Width="Auto" Text="{Binding Mode=TwoWay, Path=Screen.Customer.Gender}" FontSize="14" />
</StackPanel>
<TextBlock Height="23" HorizontalAlignment="Left" Name="textblock15" VerticalAlignment="Top" Width="Auto" Text="{Binding Mode=TwoWay, Path=Screen.Property1}" FontSize="14" />
</StackPanel>
</Border>
</UserControl>
Notice that we can print any screen data using binding such as Path=Screen.Property1.
Source code including the last post, printing using Word in C#, is available here.