Select to view content in your preferred language

Silverlight printing sample

10252
52
05-25-2011 11:22 AM
DanDong
Deactivated User
Hi everyone,

I am using the silverlight printing sample from code gallery (http://www.arcgis.com/home/item.html?id=e361c2cc69784fcba34358d0458f66e3).

According to the ReadMe, I should add a reference to the MapPrintingControls.dll (located at
MapPrintingControls/Bin/Release) to my silverlight application.

But I cannot find MapPrintingControls.dll in that path and neither the whole download folder, thus I cannot add this reference. Does anyone has clue for this? or if you have the dll, could you please share it with me 🙂 Really appreciate.
0 Kudos
52 Replies
DominiqueBroux
Esri Frequent Contributor
In my application, I actually use a button (not a toggle button) to show the print dialog. Is there a way to get a zoomed map in the print dialog?

Look at this thread http://forums.arcgis.com/threads/14270-Printing-in-SL-2.0-comparsion. there is some explanation on how and when the print extent is defined and how a button can be used to control that.



I use the 'layerids' to limit the layers displayed in the legend. But I didn't find the similar thing in the legend in the printer style.

I don't understand. Why could you not use the LayerIds property for the second legend as well?
0 Kudos
DanDong
Deactivated User
Hi Dominique, thank you for your advice! I follow the method in the thread and set the isactive with codes. I use a common button to open the print dialog. But the extent in the print page still has some issue. It looks like only the printable area in the red rectangle is changed as I zoom in the map, but the extent stays as the whole state without being zoomed in...:(  [ATTACH]6980[/ATTACH]  [ATTACH]6981[/ATTACH]

I paste this piece of codes.

private void PrintBtn_Click(object sender, RoutedEventArgs e)
        {
            if (MapPrinterDialog.Visibility == System.Windows.Visibility.Collapsed)
            {
                MapPrinterDialog.Visibility = System.Windows.Visibility.Visible;
                mapPrinterWithDialog.IsActive = true;
            }
            else
            {
                MapPrinterDialog.Visibility = System.Windows.Visibility.Collapsed;
                mapPrinterWithDialog.IsActive = false;
            }
        }


<!--set the print dialog-->
            <controls:MapPrinterDialog x:Name="MapPrinterDialog" Background="White" Width="350" Height="400" Style="{StaticResource MyMapPrinterDialogStyle}" Visibility="Collapsed" >
                <controls:MapPrinter x:Name="mapPrinterWithDialog" Map="{Binding ElementName=MyMap}" Style="{StaticResource WithLegend}"
                                     Title="DIRT" PageChanged="mapPrinter_PageChanged" 
                   IsScaleFixed="True" Scale="2000000" />
                <!--IsActive="{Binding ElementName=PrintBtn }"-->
            </controls:MapPrinterDialog>           
            <controls:MapPrinterIndicator MapPrinter="{Binding ElementName=mapPrinter}" />
0 Kudos
DominiqueBroux
Esri Frequent Contributor
I am not sure to understand the issue.
The PrintExtent is not supposed to change when zooming in the main map nor in the print dialog map (but you could do that by your own development).

The print extent changes when:
     - you use the 'Defined print extent' command
     - you set the PrintExtent property by code
     - you activate the mapprinter, the printextent is set to the current map extent (at the condition that it was not already set)

As you have fixed the scale, you have also to consider that the printed extent will be different from the desired print extent in order to respect the scale.

Hope this help.
0 Kudos
DanDong
Deactivated User
Hey Dominique, thank you very much, I see your point. I comment the fixed scale part in MapPrinter
IsScaleFixed="True" Scale="2000000"


After this, every time I click the button to fold or unfold the MapPrinterDialog, the extent will change. I don't need PrintExtent to be changed when zooming in the main map> But with the fixed scale, when I click the button to unfold the MapPrinterDialog, the print extent doesn't change. I mean it should change since I use its 'isactive' property in the button click event.

I have another question related to the legend in MapPrinter. This legend is located in the style 'WithLegend'. Then how should I call this legend in the code behind?? Please see the red letters in the codes below. Even I have given a name to this legend (x:Name = "PrintLegend"), I still cannot call this legend in codes.
What I want to implement is that in the beginning, only the 'Visible Layers' is displayed on the legend. But as the user play around with the website, a few graphicslayers will display on the legend to with results from spatial query, find or buffer task. So with the legend control in this application (not the one in print dialog), I wrote this to add another item to the legend: MyLegend.LayerIDs.SetValue("MySelectionGraphicsLayer",legendIDcount);
But I was unable to write the similar code to PrintLegend 😞
Any thoughts on this?

 <!-- Legend -->
                                            <Border Background="{TemplateBinding Background}">
                                                <StackPanel>
                                                    <TextBlock Text="Legend" FontWeight="Bold" HorizontalAlignment="Center"/>
                                                    <esri:Legend x:Name="PrintLegend" Map="{Binding ElementName=PrintMap}" LayerIDs="Visible Layers,,,">
                                                        <esri:Legend.Style>
                                                            <Style TargetType="esri:Legend">
                                                                <Setter Property="LayerItemsMode" Value="Flat" />
                                                                <Setter Property="Template">
                                                                    <Setter.Value>
                                                                        <ControlTemplate TargetType="esri:Legend">
                                                                            <ItemsControl ItemsSource="{TemplateBinding LayerItemsSource}">
                                                                                <ItemsControl.ItemTemplate>
                                                                                    <DataTemplate>
                                                                                        <StackPanel Orientation="Vertical">

                                                                                            <!--Layer Item-->
                                                                                            <TextBlock Text="{Binding Label}" FontWeight="SemiBold"/>

                                                                                            <!--Legend Items-->
                                                                                            <ItemsControl ItemsSource="{Binding LegendItems}" >
                                                                                                <ItemsControl.ItemTemplate>
                                                                                                    <DataTemplate >
                                                                                                        <ContentPresenter Content="{Binding}" ContentTemplate="{Binding Template}" />
                                                                                                    </DataTemplate>
                                                                                                </ItemsControl.ItemTemplate>
                                                                                            </ItemsControl>
                                                                                        </StackPanel>
                                                                                    </DataTemplate>
                                                                                </ItemsControl.ItemTemplate>
                                                                            </ItemsControl>
                                                                        </ControlTemplate>
                                                                    </Setter.Value>
                                                                </Setter>
                                                            </Style>
                                                        </esri:Legend.Style>
                                                    </esri:Legend>
                                                </StackPanel>

                                            </Border>
0 Kudos
DominiqueBroux
Esri Frequent Contributor

But with the fixed scale, when I click the button to unfold the MapPrinterDialog, the print extent doesn't change.

Difficult to help you out. The sample is working well this way so I guess the problem is coming from one of your modification.


This legend is located in the style 'WithLegend'. Then how should I call this legend in the code behind??

As the names are defined in a template, you can't easily use the names to access the elements.
The simplest way is to hook up an handler to events such as Refreshed or Loaded and put your code in this handler.
0 Kudos
DanDong
Deactivated User
Thank you Dominique! I see your point. I did modify the sample a lot...so I agree that may cause the issue.

Regard to accessing the element in template. I followed your suggestion. I created a loaded event for the legend inside the style. The codes for this event are as below. By doing this, I can access the element in the template and change its properties' value.

I have another question related to the 'withlegend' template. I see there is a big number in the red rectangle on the print dialog and it is the page number. I went through the map part in the template, but didn't find where I can modify to disable this big number....I only have one page to print out, so I think I don't need this big number 😛 [ATTACH]7097[/ATTACH] Thank you!

Legend printLegend;

//this event used in print legend style to get access to the element in the style
        private void PrintLegend_Loaded(object sender, RoutedEventArgs e)
        {
            printLegend = sender as Legend;
            printLegend.LayerIDs.SetValue("MySelectionGraphicsLayer", legendIDcount);
        }


<!-- Map-->
                                            <Border BorderBrush="Black" BorderThickness="1">                                                                                           
                                            <esri:Map x:Name="PrintMap" IsLogoVisible="False" 
              controls:CloneMap.Map="{TemplateBinding Map}"
              controls:SurrogateBinder.OverviewMapPrinter="{Binding RelativeSource={RelativeSource TemplatedParent}}">
                                                <controls:PrintOverviewLayer>
                                                    <controls:PrintOverviewLayer.ExtentFillSymbol>
                                                        <esri:SimpleFillSymbol BorderBrush="Red" BorderThickness="3" Fill="Transparent" />
                                                    </controls:PrintOverviewLayer.ExtentFillSymbol>
                                                </controls:PrintOverviewLayer>
                                            </esri:Map>
                                            </Border>
0 Kudos
DominiqueBroux
Esri Frequent Contributor

I see there is a big number in the red rectangle on the print dialog and it is the page number. I went through the map part in the template, but didn't find where I can modify to disable this big number....


That's managed by the property 'TextSymbol' of the layer 'PrintOverview'.

So you can either set the TextSymbol to null or set it's foreground color to transparent.

Something like:
<controls:PrintOverviewLayer TextSymbol="{x:Null}">
   <controls:PrintOverviewLayer.ExtentFillSymbol>
       <esri:SimpleFillSymbol BorderBrush="Red" BorderThickness="3" Fill="Transparent" />
   </controls:PrintOverviewLayer.ExtentFillSymbol>
</controls:PrintOverviewLayer>
0 Kudos
DanDong
Deactivated User
That works! Many thanks to you, Dominique! 🙂 Also thanks a lot for such a powerful print sample! It really helps me out. Without this, I cannot even think about implementing such a convenient print tool. 😛

I am now working on the scale of the map. Since I didn't give a fixed scale to the MapPrinter control, I am thinking to make one of the textblocks in the footer to display the current map scale. Originally this textblock is binding to the textbox which is used to get the scale value from user's input. Any thoughts on how to let it show the current map scale? Thank you!

<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="2" Grid.ColumnSpan="2"
 Text="{Binding Scale, RelativeSource={RelativeSource TemplatedParent}, StringFormat='1 : {0:F0} '}" />
0 Kudos
DominiqueBroux
Esri Frequent Contributor
Thanks for your nice words. I am glad this sample was usefull for you:)

Concerning your question about the scale, your code should work since the scale mapprinter property is set to the scale (actually scale denominator) the print will be done. So you can use it to display the scale in the dialog or in the print out.

Note that this scale won't change when you zoom the map but only when you change the print extent.
Note also that the scale can change during the print process after the user selects the printer and the orientation since the scale is depending on the printeable area.
0 Kudos
DanDong
Deactivated User
Hey Dominique, I see that the textblock in the mapprinter is bind to the Scale denominator, instead of the textbox used for user's input. But no matter how I change the print extent, the footer stays 1�?0 �?0 is default value in the textbox�?. Only after I change 0 to other value, the footer will change accordingly. Is this because the scale of the map hasn't been set yet? Then how should I get the current scale of the map? I noticed that there are a few threads related to this question and there should be a equation to calculate the current scale.

Text="{Binding Scale, RelativeSource={RelativeSource TemplatedParent}, StringFormat='1 : {0:F0} '}" 
0 Kudos