Select to view content in your preferred language

Printing map and text in Silverlight

3101
7
02-25-2011 09:05 AM
by Anonymous User
Not applicable
Original User: tgorrie

Can any one help me print out a layout in silverlight; that includes the map, title and legend. I am unable to combine them.

I have found one example on the forums but it is extremely complicated. Any help is appreciated.

Thanks.
         
*CODE*
Dim pdoc As New PrintDocument()
            AddHandler pdoc.PrintPage, Sub(p, args)
                                           args.PageVisual = MyMap
                                           args.HasMorePages = False
                                       End Sub

            AddHandler pdoc.EndPrint, Sub(p, args) MessageBox.Show("Print operation complete")

            pdoc.Print("Map")
0 Kudos
7 Replies
DominiqueBroux
Esri Frequent Contributor
There is a print sample here : http://www.arcgis.com/home/item.html...4358d0458f66e3
With this sample you can print title and legend (e.g. print result with legend).
0 Kudos
by Anonymous User
Not applicable
Original User: erpiant

Good Morning Dominique!

I have successfully implemented printing the map with legend using your example and setting the 'WithLegend' on the 'Style' attribute on the MapPrinterDialog defined on my 'MainPage.xaml':

            <userControls:WindowPanel x:Name="PrintDialogPanel" ContentTitle="PDF Printing" Collapsible="False" Closable="True" Minimized="False" Visibility="Collapsed" Width="470" Height="600" >
                <controls:MapPrinterDialog Height="410" Width="340" >
                    <controls:MapPrinter x:Name="mapPrinter" Map="{Binding ElementName=MyMap}"  Style="{StaticResource WithLegend}"/>
                </controls:MapPrinterDialog>
            </userControls:WindowPanel>



I defined the 'WithLegend' template in the UserResources section of the MainPage.xaml.

Also, in the code-behind page, I return the results of a query to a datagrid ('SchoolsDataGrid') located on the MainPage.xaml:

                        <slData:DataGrid x:Name="SchoolsDataGrid" AutoGenerateColumns="False" HeadersVisibility="All"
                                Background="White">
                            <slData:DataGrid.Columns>
                                    <slData:DataGridTextColumn CanUserSort="False" SortMemberPath="NAME" Binding="{Binding Attributes[NAME]}" Header="School Name"/>
                                <slData:DataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[PHONE]}" Header="School Phone"/>
                                <slData:DataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[TYPE]}" Header="Type"/>
                                <!--<slData:DataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[ADDRESS]}" Header="Address"/>-->
                            </slData:DataGrid.Columns>
                        </slData:DataGrid>



Is it possible to add a datagrid to the 'WithLegend' template? And if so, how? I was attempting to add it between the map and the text printout at the bottom of the map printout page but I am unsure of the syntax to use to bind the text column data to the templated parent so I used ??? as a placeholder for the correct syntax:

                                    <!--Third Row of Grid-->
                                    <StackPanel Orientation="Vertical" Background="{TemplateBinding Background}" Grid.Row="2">
                                        <slData:DataGrid>
                                            <slData:DataGrid.Columns>
                                                <slData:DataGridTextColumn ??? />
                                            </slData:DataGrid.Columns>
                                        </slData:DataGrid>
                                    </StackPanel>

                                    <!--Fourth Row of Grid-->
                                    <!-- Footer -->
                                    <Grid Background="{TemplateBinding Background}" Grid.Row="3" Grid.ColumnSpan="2">
                                        <TextBlock HorizontalAlignment="Right" VerticalAlignment="Center"
              Text="{Binding Now, RelativeSource={RelativeSource TemplatedParent}, StringFormat='Printed {0:d} '}" />
                                        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="2" Grid.ColumnSpan="2"
            Text="{Binding Scale, RelativeSource={RelativeSource TemplatedParent}, StringFormat='1 : {0:F0} '}" />
                                        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal">
                                            <TextBlock Text="{Binding CurrentPage, RelativeSource={RelativeSource TemplatedParent}, StringFormat='Page {0} '}" />
                                            <TextBlock Text="{Binding PageCount, RelativeSource={RelativeSource TemplatedParent}, StringFormat='/ {0}'}" />
                                        </StackPanel>
                                    </Grid>
                                </Grid>

What is the correct syntax to use to bind the printout datagrid to the web map datagrid so that I may printout a map with legend plus a datagrid in Silverlight. I know I can set the 'Style' attribute only once on the MapPrinterDialog control. None of the 'Style' template options provide a map with both a legend and a datagrid on the printout. I thought the easiest way was to add code for a datagrid to the 'WithLegend' template.

Please explain or provide example.

Thanks, Liz
0 Kudos
AnastasiaAourik
New Contributor II
Is the download link for this source working?  I am trying to download it but it never completes.
Anyone else having this problem?
0 Kudos
by Anonymous User
Not applicable
Original User: dbroux

Hi Elizabeth,

It's possible to add a datagrid to the print template. The point to take care is how to define the ItemsSource of this datagrid.

If you have only one datagrid in your template you can use the datacontext of the mapprinter to store the itemssource (another more generic option would have been to use the DataItems ot the MapPrinter but likely you don't need that).

You don't have to change the binding of the columns, just add a binding to the ItemsSource="{Binding}".

Something like:
<slDataataGrid AutoGenerateColumns="False" HeadersVisibility="All" 
Background="White" ItemsSource="{Binding}">
<slDataataGrid.Columns>
<slDataataGridTextColumn CanUserSort="False" SortMemberPath="NAME" Binding="{Binding Attributes[NAME]}" Header="School Name"/>
<slDataataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[PHONE]}" Header="School Phone"/>
<slDataataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[TYPE]}" Header="Type"/>
<!--<slDataataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[ADDRESS]}" Header="Address"/>-->
</slDataataGrid.Columns>
</slDataataGrid>


Now you have to initialize by code the datacontext of the mapprinter to the list of graphics.
At the same time you already do it for the main data grid, do it for the mapprinter:
    ScoolsDatagrid.ItemsSource = something;
    MyMapPrinter.Datacontext = thesamething;
0 Kudos
ElizabethPianta
New Contributor
Thanks Dominique for the reply. I have not been able to successfully implement the solution you provided to display the datagrid user controls on MapPrinter dialog or on the map printout. Also, I have two datagrids (SchoolsDataGrid and DaycareDataGrid.) I tried to implement the solution by removing one of the datagrids, but still no success.
I may not be correctly initializing the datacontext of the mapprinter to the list of graphics as you advised. The vb code I used to initialize the main datagrid to the list of graphics:

        Dim resultFeaturesBinding As New Binding("LastResult.Features")
        resultFeaturesBinding.Source = _schoolsQueryTask

        SchoolsDataGrid.SetBinding(DataGrid.ItemsSourceProperty, resultFeaturesBinding)

To set it to the same thing, do I need to define a second resultFeaturesBinding? And do I set the datacontext as you mentioned:
       mapPrinter.DataContext = ???
or set the value on the mapPrinter?
       mapPrinter.SetValue = ???

Thanks for helping me with this part of the PDF print functionality sample. Much appreciated.
0 Kudos
by Anonymous User
Not applicable
Original User: dbroux


To set it to the same thing, do I need to define a second resultFeaturesBinding?

Yes, you can do the same thing with the MapPrinter.DataContextProperty.

Another simpler approach is that you initialize the datacontext when the query is completed (so you don't need a binding).

Something like:

private void QueryTask_ExecuteCompleted(object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs args)
{
  FeatureSet featureSet = args.FeatureSet;
  if (featureSet == null || featureSet.Features.Count < 1)
  {
    MessageBox.Show("No features returned from query");
    return;
  }
  MyMapPrinter.DataContext = featureSet.Features;
  .......



Also, I have two datagrids (SchoolsDataGrid and DaycareDataGrid.)

If your 2 datagrids can't share the same ItemsSource, it means that you need 2 ItemsSource and that you can't store them directly in the datacontext without implementing your own view model class with these sources.

In this case, the dev steps are :
1) Create a new 'MapPrinterViewModel' class
2) Add two properties of type IEnumerable<Graphics> (lets say Graphics1 and Graphics2)
3) Initialize the MapPrinter.DataContext with an instance of this class
4) When it's ready, initialize Graphics1 and Graphics2 with the list of graphics that you want to see in your datagrid 1 and 2.
5) In your MapPrinter control template, bind the ItemsSource of your 2 datagrids to these 2 properties.
<slData:DataGrid x:Name="DataGrid1"
ItemsSource="{Binding Graphics1}"      ....... 
>
<slData:DataGrid.Columns>
......
 
<slData:DataGrid x:Name="DataGrid2"ItemsSource="{Binding Graphics2}" ......>
<slData:DataGrid.Columns>......

Should work....
0 Kudos
TamiOnstad
New Contributor III
Sorry to join the party late, but I ran across this posting as I was trying to implement the same scenario - generating the print dialog using WithLegend style, but adding a dataform to the printed map.

I'm no expert in Silverlight, so I have struggled with this concept and trying to integrate what I know how to do (create the dataform from my featurelayer attributes, which works perfectly when the dataform is created by itself as a control in MainPage.xaml and bound in code-behind) with the printer dialog.

Where I am struggling is how to use my dataform with the generic.xaml and the WithLegend style template.  I initially put the dataform inside the WithLegend template in generic.xaml, but I could not get access to the dataform from MainPage.xaml.vb code (which is where the binding happens at run-time). 

Any help here would be greatly appreciated.  Does the WithLegend Style XAML need to reside somewhere else other than generic.xaml for this to work?
0 Kudos