<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>gruchalski.com &#187; Silverlight/WPF</title>
	<atom:link href="http://gruchalski.com/category/silverlightwpf/feed/" rel="self" type="application/rss+xml" />
	<link>http://gruchalski.com</link>
	<description>confessions of a ria developer</description>
	<lastBuildDate>Sat, 08 May 2010 16:43:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Yet another ViewStack control for Silverlight</title>
		<link>http://gruchalski.com/2009/12/15/yet-another-viewstack-control-for-silverlight/</link>
		<comments>http://gruchalski.com/2009/12/15/yet-another-viewstack-control-for-silverlight/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 23:41:16 +0000</pubDate>
		<dc:creator>radekg</dc:creator>
				<category><![CDATA[Silverlight/WPF]]></category>

		<guid isPermaLink="false">http://gruchalski.com/?p=418</guid>
		<description><![CDATA[In one of my recent Silverlight projects I had to use a ViewStack control. There is few of these already available here and there but I thought it might be fun to build new one from scratch. As image speaks more than words here is the sample. And here is the source code. Hope this [...]]]></description>
			<content:encoded><![CDATA[<p>In one of my recent Silverlight projects I had to use a ViewStack control. There is few of these already available here and there but I thought it might be fun to build new one from scratch. As <em>image speaks more than words</em> here is the sample.</p>
<p><div id="silverlightControlHost"><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="400" height="300"><param name="source" value="http://gruchalski.com/wp-content/uploads/2009/12/ViewStackTestApp.xap"/><param name="background" value="white" /><param name="minRuntimeVersion" value="4.0.41108.0" /><param name="autoupgrade" value="true" /><param name="enableHtmlAccess" value="true" /><a href="http://go.microsoft.com/fwlink/?LinkID=149156" style="text-decoration: none;"><img src="http://storage.timheuer.com/sl4wp-ph.png" alt="Install Microsoft Silverlight" style="border-style: none; width:400px; height:200px"/></a></object><iframe style="visibility:hidden;height:0;width:0;border:0px" id="_sl_historyFrame"></iframe></div><br /></p>
<p><a href="/wp-content/uploads/2009/12/ViewStack.zip">And here is the source code</a>.</p>
<p>Hope this helps anyone.</p>
]]></content:encoded>
			<wfw:commentRss>http://gruchalski.com/2009/12/15/yet-another-viewstack-control-for-silverlight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Printing data on multiple pages with Silverlight 4</title>
		<link>http://gruchalski.com/2009/11/20/printing-data-on-multiple-pages-with-silverlight-4/</link>
		<comments>http://gruchalski.com/2009/11/20/printing-data-on-multiple-pages-with-silverlight-4/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 22:52:29 +0000</pubDate>
		<dc:creator>radekg</dc:creator>
				<category><![CDATA[Silverlight/WPF]]></category>

		<guid isPermaLink="false">http://gruchalski.com/?p=385</guid>
		<description><![CDATA[This week at PDC09 Microsoft unveiled latest Silverlight release &#8211; first beta of version 4. One of the new features is printing support. There is a great video introduction to printing published by Tim Heuer. It show the basics, after watching it my first question was how to print the data on multiple pages. Here [...]]]></description>
			<content:encoded><![CDATA[<p>This week at <a href="http://microsoftpdc.com">PDC09</a> Microsoft unveiled latest Silverlight release &#8211; first beta of version 4. One of the new features is printing support. There is a great <a href="http://silverlight.net/learn/videos/all/printing-api-basics/">video introduction to printing</a> published by <a href="http://timheuer.com/blog/">Tim Heuer</a>. It show the basics, after watching it my first question was how to print the data on multiple pages. Here is how I do it. This application is a cut down version of the app published by Tim on <a href="http://silverlight.net/learn/videos/all/printing-api-basics/">silverlight.net</a>.</p>
<p>In this sample we are going to print list of people and display sample header showing page number and some random title. Let&#8217;s jump in.</p>
<p>Let&#8217;s start with XAML:</p>
<pre name="code" class="xml">
&lt;UserControl x:Class=&quot;PrintingTest.MainPage&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    xmlns:data=&quot;clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data&quot;
    mc:Ignorable=&quot;d&quot;
    d:DesignHeight=&quot;300&quot; d:DesignWidth=&quot;400&quot;&gt;
    &lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;White&quot;&gt;
        &lt;data:DataGrid
            ItemsSource=&quot;{Binding}&quot;
            Height=&quot;247&quot; HorizontalAlignment=&quot;Left&quot;
            Margin=&quot;12,41,0,0&quot; Name=&quot;dataGrid1&quot;
            VerticalAlignment=&quot;Top&quot; Width=&quot;376&quot; /&gt;
        &lt;Button
            Content=&quot;Print data&quot; Height=&quot;23&quot;
            HorizontalAlignment=&quot;Left&quot; Margin=&quot;12,12,0,0&quot;
            Name=&quot;PrintDataBtn&quot; VerticalAlignment=&quot;Top&quot;
            Width=&quot;126&quot; Click=&quot;PrintDataBtn_Click&quot; /&gt;
    &lt;/Grid&gt;
&lt;/UserControl&gt;
</pre>
<p>Next is the <code>Person</code> class which is exactly the same as in the original video:</p>
<pre name="code" class="csharp">
using System;

namespace PrintingTest
{
    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public string FullName {
            get {
                return string.Concat(FirstName, &quot; &quot;, LastName);
            }
        }
    }
}
</pre>
<p>And now the most important part &#8211; the code behind. The <code>MainPage</code> class wires up the <code>Loaded</code> event and when the app is loaded it populates the list of people as well as sets the <code>DataContext</code> on <code>LayoutRoot</code>.</p>
<pre name="code" class="csharp">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Printing;
using System.Windows.Media;

namespace PrintingTest
{
    public partial class MainPage : UserControl
    {

        public MainPage()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            List&lt;Person&gt; people = new List&lt;Person&gt;();
            for (int i = 0; i &lt; 20; i++)
            {
                people.Add(new Person() { FirstName = &quot;Al&quot;, LastName = &quot;Pacino&quot;, Age = 69 });
                people.Add(new Person() { FirstName = &quot;Robert&quot;, LastName = &quot;De Niro&quot;, Age = 66 });
                people.Add(new Person() { FirstName = &quot;Val&quot;, LastName = &quot;Kilmer&quot;, Age = 50 });
                people.Add(new Person() { FirstName = &quot;John&quot;, LastName = &quot;Voight&quot;, Age = 71 });
                people.Add(new Person() { FirstName = &quot;Tom&quot;, LastName = &quot;Sizemore&quot;, Age = 48 });
            }
            LayoutRoot.DataContext = people;
        }

        private void PrintDataBtn_Click(object sender, RoutedEventArgs e)
        {
            // header height:
            double headerHeight = 70.0;
            // footer height:
            double footerHeight = 30.0;
            // single line height:
            double tboxHeight = 20.0;
            // how many elements can we place on one page?
            int numElements = -1;
            // current page number:
            int page = 1;
            // total number of pages to print:
            int totalPages = 0;
            // number of the current item:
            int counter = 1;

            PrintDocument doc = new PrintDocument();
            doc.PrintPage += (s, args) =&gt;
            {
            };
           doc.Print();
        }

    }
}
</pre>
<p>The code below is responsible for printing and should be placed inside <code>doc.PrintPage</code> lambda. Let&#8217;s discuss what is going on there first.</p>
<p>When the application attempts to compose first page the number of elements per page and total number of pages is calculated. Next, the header is created. It is a <code>Grid</code> with two <code>TextBlock</code>s. First of the text blocks holds the title while the second one displays current and the total pages numbers; header is created separately for each page.</p>
<p>Once the header is constructed the <code>dynamicPanel</code> <code>StackPanel</code> is created and previously constructed <code>headerGrid</code> is added to its <code>Children</code> list. Next, we query <code>dataGrid1.ItemsSource</code> for the first of people to display on current page. We skip as many elements as we fitted on previous pages and take number of elements for the current one.</p>
<p>The penultimate step is enumerating over <code>ppl</code> list and for each one of them create a <code>StackPanel</code> with two <code>TextBlock</code>s. First displays the name of the person, second one the age. Finally we set <code>HasMorePages</code>.</p>
<p><code>HasMorePages</code> is the key to multiple pages printing. As long as it is set to <code>true</code> Silverlight expects more pages to be printed. That&#8217;s why when the number of current page is equal to total number of pages we set it to <code>false</code>. At this point printing the document is finished.</p>
<p>Here is the code:</p>
<pre name="code" class="csharp">
                if (page == 1)
                {
                    numElements = (int)((args.PrintableArea.Height - headerHeight - footerHeight) / tboxHeight);
                    double totalItems = (double)((List&lt;Person&gt;)dataGrid1.ItemsSource).Count;
                    totalPages = (int)Math.Ceiling(totalItems / (double)numElements);
                }

                Grid headerGrid = new Grid()
                    {
                        Width = args.PrintableArea.Width,
                        Height = headerHeight
                    };
                headerGrid.RowDefinitions.Add(new RowDefinition());
                headerGrid.ColumnDefinitions.Add(new ColumnDefinition());
                headerGrid.ColumnDefinitions.Add(new ColumnDefinition());

                TextBlock headerTitle = new TextBlock()
                {
                    Text = &quot;Contact list&quot;,
                    HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
                    VerticalAlignment = System.Windows.VerticalAlignment.Center,
                    Margin = new Thickness(50,0,0,0),
                    FontSize = 20
                };
                TextBlock pageCounter = new TextBlock()
                {
                    Text = string.Concat(&quot;Page &quot;, page, &quot; of &quot;, totalPages),
                    HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
                    VerticalAlignment = System.Windows.VerticalAlignment.Center,
                    Margin = new Thickness(0, 0, 50, 0)
                };
                headerGrid.Children.Add(headerTitle);
                headerGrid.Children.Add(pageCounter);
                Grid.SetColumn(headerTitle, 1);
                Grid.SetColumn(pageCounter, 2);

                StackPanel dynamicPanel = new StackPanel();
                // add header to display list:
                dynamicPanel.Children.Add(headerGrid);

                IEnumerable&lt;Person&gt; ppl = ((List&lt;Person&gt;)dataGrid1.ItemsSource).Skip((page - 1) * numElements).Take(numElements);

                foreach (Person p in ppl)
                {
                    // create stack panel for each person:
                    StackPanel namePanel = new StackPanel();
                    namePanel.Orientation = Orientation.Horizontal;

                    TextBlock counterBlock = new TextBlock();
                    counterBlock.TextAlignment = TextAlignment.Right;
                    counterBlock.Margin = new Thickness(0, 0, 5, 0);
                    counterBlock.Text = string.Concat(counter, &quot;.&quot;);
                    counterBlock.Height = tboxHeight;
                    counterBlock.Width = 50.0;

                    TextBlock nameBlock = new TextBlock();
                    nameBlock.Text = p.FullName;
                    nameBlock.Height = tboxHeight;

                    TextBlock ageBlock = new TextBlock();
                    ageBlock.Text = string.Concat(&quot;who is &quot;, p.Age, &quot; years old&quot;);
                    ageBlock.Foreground = new SolidColorBrush(Colors.Red);
                    ageBlock.Margin = new Thickness(5, 0, 0 , 0);
                    ageBlock.Height = tboxHeight;

                    namePanel.Children.Add(counterBlock);
                    namePanel.Children.Add(nameBlock);
                    namePanel.Children.Add(ageBlock);
                    dynamicPanel.Children.Add(namePanel);

                    counter++;
                }

                args.HasMorePages = !(page == totalPages);
                args.PageVisual = dynamicPanel;

                page++;
</pre>
<p>Full source code can be downloaded <a href="/wp-content/uploads/2009/11/PrintingTest.zip">from here</a>. You can test working example below, please make sure you use Silverlight 4 beta. It can be installed <a href="http://silverlight.net/getstarted/silverlight-4-beta/#tools">from this location</a>.</p>
<p><span id="more-385"></span></p>
<p><div id="silverlightControlHost"><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="400" height="300"><param name="source" value="http://gruchalski.com/wp-content/uploads/2009/11/PrintingTest.xap"/><param name="background" value="white" /><param name="minRuntimeVersion" value="4.0.41108.0" /><param name="autoupgrade" value="true" /><param name="enableHtmlAccess" value="true" /><a href="http://go.microsoft.com/fwlink/?LinkID=149156" style="text-decoration: none;"><img src="http://storage.timheuer.com/sl4wp-ph.png" alt="Install Microsoft Silverlight" style="border-style: none; width:400px; height:200px"/></a></object><iframe style="visibility:hidden;height:0;width:0;border:0px" id="_sl_historyFrame"></iframe></div><br /></p>
<p>Sample PDF output can be seen <a href="/wp-content/uploads/2009/11/PeoplePrintOutput.pdf">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://gruchalski.com/2009/11/20/printing-data-on-multiple-pages-with-silverlight-4/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Why crossdomain.xml is even more than a good thing</title>
		<link>http://gruchalski.com/2009/05/22/why-crossdomainxml-is-even-more-than-a-good-thing/</link>
		<comments>http://gruchalski.com/2009/05/22/why-crossdomainxml-is-even-more-than-a-good-thing/#comments</comments>
		<pubDate>Fri, 22 May 2009 01:19:16 +0000</pubDate>
		<dc:creator>radekg</dc:creator>
				<category><![CDATA[Adobe Flex/AIR]]></category>
		<category><![CDATA[Silverlight/WPF]]></category>

		<guid isPermaLink="false">http://gruchalski.com/?p=271</guid>
		<description><![CDATA[For a long time I couldn&#8217;t really understand what crossdomain.xml is&#160;for. Today, after finishing one the Flex projects I finally figured it out. At&#160;least one of two reasons. About 4 years ago Martijn de Visser described one of them &#8211; defending your internal network from the attacks. But there is another way reason why crossdomain.xml [...]]]></description>
			<content:encoded><![CDATA[<p>For a long time I couldn&#8217;t really understand what <em>crossdomain.xml</em> is&nbsp;for. Today, after finishing one the Flex projects I finally figured it out. At&nbsp;least one of two reasons. About 4 years ago <a href="http://www.martijndevisser.com/blog/about/">Martijn de Visser</a> <a href="http://www.martijndevisser.com/blog/2005/why-crossdomainxml-is-a-good-thing/">described one of them</a> &#8211; defending your internal network from the attacks. But there is another way reason why crossdomain.xml is good.</p>
<p>Let&#8217;s say I&#8217;m developing some smart module and I let people download and load it from their domains but there are some specific sites that I&nbsp;want to prohibit. I&#8217;m going to use this very simple module to demonstrate how this can be achieved.</p>
<pre>[sourcecode lang='xml']
<?xml version="1.0"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%">
 <mx:Label text="I'm the protected module" />
</mx:Module>
[/sourcecode]</pre>
<p>Suppose that I let <em>http://www.friend1.com</em> and <em>http://www.friend2.com</em> use it but <em>http://www.pron.com</em> shouldn&#8217;t be allowed. When I modify the code a bit I will use Flash Player sandboxing to do so.</p>
<pre>[sourcecode lang='as3']
<?xml version="1.0"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"
 creationComplete="onCreated();">
 <mx:Script>
  <![CDATA[

   import flash.net.URLRequest;
   import flash.net.URLLoader;
   import flash.events.SecurityErrorEvent;
   import flash.events.Event;
   import flash.events.IOErrorEvent;
   import flash.external.ExternalInterface;

   private function onCreated():void {
    var url:URLRequest = new URLRequest();
    url.url = "http://www.mymodulesfactory.com/check.cfm"
    var loader:URLLoader = new URLLoader();
    loader.addEventListener(Event.COMPLETE, onComplete);
    loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
    // this one really doesn't matter
    // I'm catching it so the error is not visible
    // in the debug player if the user uses it and check.cfm doesn't exist
    // check.cfm does not have to exist
    loader.addEventListener(IOErrorEvent.IO_ERROR, onComplete);
    loader.load(url);
   }
   private function onComplete(event:Event):void {
    // everything is fine, I am allowed to access the domain, ignore
   }
   private function onSecurityError(event:SecurityErrorEvent):void {
    ExternalInterface.call(
     "f = function() { alert('you are not allowed to use this extension');"
     + "top.location.href='http://www.mymodulesfactory.com/license.cfm'; }"
    );
   }
  ]]&gt;
 </mx:Script>
 <mx:Label text="I'm the protected module" />
</mx:Module>
[/sourcecode]</pre>
<p>Next, I have to create following crossdomain.xml file:</p>
<pre>[sourcecode lang='xml']
<cross-domain-policy
 xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFile.xsd">
 <allow-access-from domain="friend1.com"/>
 <allow-access-from domain="friend2.com"/>
 <!-- any other friends I like to add in the future go here -->
</cross-domain-policy>
[/sourcecode]</pre>
<p>The extended example in the conjunction with the above policy file protects this module from being used by the <em>http://www.pron.com</em>. When the module is created it simply calls home, policy file is returned and the module checks if the domain from which it is being used is allowed. Because <em>http://www.pron.com</em> is not on the list <em>SecurityErrorEvent</em> is fired and browser&#8217;s <em>alert</em> message pops up. Once the user clicks <em>OK</em> button he will be redirected to the module&#8217;s license. This is just a prototype but it should be quite solid.</p>
<p>I&#8217;ve created this code outside the IDE so it may have some bugs.</p>
<p>This approach should be very easy to apply in Silverlight as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://gruchalski.com/2009/05/22/why-crossdomainxml-is-even-more-than-a-good-thing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
