﻿<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
  <channel>
    <title>Silverlight, WCF, ASP.NET MVC</title>
    <description />
    <link>http://lukaskubis.net/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.6.0.0</generator>
    <language>en-US</language>
    <blogChannel:blogRoll>http://lukaskubis.net/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>My name</dc:creator>
    <dc:title>Silverlight, WCF, ASP.NET MVC</dc:title>
    <geo:lat>0.000000</geo:lat>
    <geo:long>0.000000</geo:long>
    <item>
      <title>MVVM #5–Modul A</title>
      <description>&lt;p&gt;Předchozí díly:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://lukaskubis.net/post/MVVM-1e28093Uvod.aspx"&gt;MVVM #1–Úvod&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://lukaskubis.net/post/MVVM-2e28093Priprava.aspx"&gt;MVVM #2–Příprava&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://lukaskubis.net/post/MVVM-3e28093Shell.aspx"&gt;MVVM #3–Shell&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://lukaskubis.net/post/MVVM-4e28093Shelle28093Design-Data.aspx"&gt;MVVM #4–Shell–Design Data&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;V dnešním díle si ukážeme jak vytvořit nový modul a jak ho provázat s hlavní aplikací.&lt;/p&gt;  &lt;p&gt;Náš první modul bude obsahovat jednoduchou funkcionalitu pro práci s časem. Vytvoříme si tedy nový projekt typu Class Library ve kterém si vytvoříme podobnou strukturu jak můžete vidět na obrázku níže.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_26.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_26.png" width="244" height="151" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Dále nesmíme zapomenout přidat referenci na knihovnu MVVMSamle.Shared. Momentálně bude náš viewmodel velice jednoduchý. Bude obsahovat pouze jednu vlastnost DateTime, která zobrazí aktuální datum a čas.&lt;/p&gt;  &lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class AViewModel : WorkspaceViewModel
{
    private string _dateTime;
    public string DateTime
    {
        get { return _dateTime; }
        set
        {
            _dateTime = System.DateTime.Now.ToString();
            OnPropertyChanged(MethodBase.GetCurrentMethod());
        }
    }

    public AViewModel()
    {
        DisplayName = Shared.Strings.ModuleA_Action1_DisplayName;
        Initialize();
    }

    protected override void OnInitialize()
    {
        DateTime = System.DateTime.Now.ToString();
    }
}&lt;/pre&gt;

&lt;p&gt;V našem View bude pouze textblock pro zobrazení této vlastnosti&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;UserControl x:Class=&amp;quot;MVVMSample.Modules.Views.AView&amp;quot;
             xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
             xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;
             xmlns:mc=&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot; 
             xmlns:d=&amp;quot;http://schemas.microsoft.com/expression/blend/2008&amp;quot; 
             mc:Ignorable=&amp;quot;d&amp;quot; 
             d:DesignHeight=&amp;quot;300&amp;quot; d:DesignWidth=&amp;quot;300&amp;quot;&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;TextBlock FontSize=&amp;quot;48&amp;quot; Text=&amp;quot;{Binding DateTime}&amp;quot;/&amp;gt;            
    &amp;lt;/Grid&amp;gt;
&amp;lt;/UserControl&amp;gt;&lt;/pre&gt;

&lt;p&gt;Pokud máme vytvořený modul, je potřeba o něm nějak říct naší hlavní Shell aplikaci. V Shell projektu upravíme třídu App. V metodě OnStartup nastavíme vlastnost GroupCommands třídy MainWindowViewModel. Zatím zde bude pouze jeden GroupCommand (Modul A). A tento GroupCommand bude mít pouze jeden Command (ViewModelA1), který po spuštění zobrazí (vytvoří novou záložku) A1View.&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        MainWindowViewModel viewModel = new MainWindowViewModel();
        viewModel.GroupCommands = new List&amp;lt;GroupCommand&amp;gt;()
            {
                new GroupCommand()
                    {
                        GroupName = Shared.Strings.GroupCommand_ModuleA,
                        Commands = new List&amp;lt; RelayCommand &amp;gt;()
                        {
                            new UICommand(param =&amp;gt; viewModel.AddWorkspace(new Modules.ViewModels.A1ViewModel()))
                            {
                                Name = Shared.Strings.Command_ViewModelA1
                            }
                        }
                    }
            };

        Shell.MainWindow mainWindow = new MainWindow();
        mainWindow.DataContext = viewModel;
        mainWindow.Show();
    &lt;/pre&gt;

&lt;p&gt;Pokud uživatel klikne na tlačítko ViewModelA1 tak se do kolekce workspaces přidá nový viewmodel A1ViewModel. Pokud by jsme aplikaci spustili, tak by se místo A1View zobrazil pouze textový popis daného viewmodelu. Proto je zapotřebí přidat do projektu nový ResourceDictionary&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;ResourceDictionary xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
                    xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;
                    xmlns:aVm=&amp;quot;clr-namespace:MVVMSample.Modules.ViewModels;assembly=MVVMSample.Modules.ModuleA&amp;quot; 
                    xmlns:aVw=&amp;quot;clr-namespace:MVVMSample.Modules.Views;assembly=MVVMSample.Modules.ModuleA&amp;quot;&amp;gt;
    
    &amp;lt;DataTemplate DataType=&amp;quot;{x:Type aVm:AViewModel}&amp;quot;&amp;gt;
        &amp;lt;aVw:AView /&amp;gt;    
    &amp;lt;/DataTemplate&amp;gt;
    
&amp;lt;/ResourceDictionary&amp;gt;&lt;/pre&gt;

&lt;p&gt;Ve kterém nastavíme pro daný viewmodel příslušné view. Všechno toto nastavení provedeme pomocí DataTemplate. Když spustíme aplikace a zobrazíme si A1View, budeme mít k dispozici i tlačítko pro Refresh, ktreré zavolá vždy metodu Initialize a provede aktualizaci času&lt;/p&gt;

&lt;p&gt;Jednoduchý modul máme za sebou a příště si ukážeme jak např. komunikovat mezi moduly.&lt;/p&gt;</description>
      <link>http://lukaskubis.net/post/MVVM-5e28093Modul-A.aspx</link>
      <author>lukask</author>
      <comments>http://lukaskubis.net/post/MVVM-5e28093Modul-A.aspx#comment</comments>
      <guid>http://lukaskubis.net/post.aspx?id=721dcd2b-f1d7-4f3c-b3c3-957fec2f1b32</guid>
      <pubDate>Fri, 04 Mar 2011 15:59:11 +1000</pubDate>
      <dc:publisher>lukask</dc:publisher>
      <pingback:server>http://lukaskubis.net/pingback.axd</pingback:server>
      <pingback:target>http://lukaskubis.net/post.aspx?id=721dcd2b-f1d7-4f3c-b3c3-957fec2f1b32</pingback:target>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://lukaskubis.net/trackback.axd?id=721dcd2b-f1d7-4f3c-b3c3-957fec2f1b32</trackback:ping>
      <wfw:comment>http://lukaskubis.net/post/MVVM-5e28093Modul-A.aspx#comment</wfw:comment>
      <wfw:commentRss>http://lukaskubis.net/syndication.axd?post=721dcd2b-f1d7-4f3c-b3c3-957fec2f1b32</wfw:commentRss>
    </item>
    <item>
      <title>MVVM #4–Shell–Design Data</title>
      <description>&lt;p&gt;Předchozí díly:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="http://lukaskubis.net/post/MVVM-1e28093Uvod.aspx"&gt;MVVM #1–Úvod&lt;/a&gt;  &lt;li&gt;&lt;a href="http://lukaskubis.net/post/MVVM-2e28093Priprava.aspx"&gt;MVVM #2–Příprava&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://lukaskubis.net/post/MVVM-3e28093Shell.aspx"&gt;MVVM #3–Shell&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;V minulých dílech jsme si připravili téměř vše podstatné až na hlavní View. To bude předmětem dnešního dílu, kde si kromě vytvoření samotného View ukážeme, jak využít “Design Data” v době návrhu. Aby jsme si tedy mohli otestovat, že náš layout bude odpovídat skutečně tomu co jsme chtěli.&lt;/p&gt;&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;Window x:Class="MVVMSample.Shell.MainWindow"
		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		Title="MainWindow" Height="768" Width="1024"&amp;gt;
	&amp;lt;Grid Background="#ffeeeeee"&amp;gt;
		&amp;lt;Grid.Resources&amp;gt;
			&amp;lt;Style x:Key="GroupCommandsTemplate" TargetType="{x:Type ItemsControl}"&amp;gt;
				&amp;lt;Setter Property="ItemTemplate"&amp;gt;
					&amp;lt;Setter.Value&amp;gt;
						&amp;lt;DataTemplate&amp;gt;
							&amp;lt;Button Content="{Binding Name}"
									Command="{Binding}"
									BorderThickness="0" 
									FontWeight="Normal"
									HorizontalContentAlignment="Left"/&amp;gt;
						&amp;lt;/DataTemplate&amp;gt;
					&amp;lt;/Setter.Value&amp;gt;
				&amp;lt;/Setter&amp;gt;
			&amp;lt;/Style&amp;gt;
			&amp;lt;DataTemplate x:Key="ClosableTabItemTemplate"&amp;gt;
				&amp;lt;DockPanel Width="120"&amp;gt;
					&amp;lt;Button Command="{Binding CloseCommand}"
							Content="X"
							DockPanel.Dock="Right"
							Width="16" Height="16" /&amp;gt;
					&amp;lt;ContentPresenter Content="{Binding DisplayName}" /&amp;gt;
				&amp;lt;/DockPanel&amp;gt;
			&amp;lt;/DataTemplate&amp;gt;
		&amp;lt;/Grid.Resources&amp;gt;
		&amp;lt;Grid.ColumnDefinitions&amp;gt;
			&amp;lt;ColumnDefinition Width="170"/&amp;gt;
			&amp;lt;ColumnDefinition Width="100"/&amp;gt;
			&amp;lt;ColumnDefinition Width="*"/&amp;gt;
		&amp;lt;/Grid.ColumnDefinitions&amp;gt;

		&amp;lt;!-- Navigacni menu - GroupCommands --&amp;gt;
		&amp;lt;ScrollViewer Grid.Row="0" 
					  Grid.RowSpan="2"
					  Grid.Column="0"
					  HorizontalScrollBarVisibility="Hidden"
					  VerticalScrollBarVisibility="Auto"&amp;gt;
			&amp;lt;ItemsControl ItemsSource="{Binding GroupCommands}"&amp;gt;
				&amp;lt;ItemsControl.ItemTemplate&amp;gt;
					&amp;lt;DataTemplate&amp;gt;
						&amp;lt;Expander Header="{Binding GroupName}"
								  IsExpanded="True"
								  Foreground="#FF97D045"
								  Margin="5,0,0,0"
								  FontWeight="Bold"&amp;gt;
							&amp;lt;ItemsControl ItemsSource="{Binding Commands}"
										  Style="{StaticResource GroupCommandsTemplate}"
										  HorizontalContentAlignment="Stretch" 
										  Margin="22,0,10,12" 
										  BorderThickness="0.0"/&amp;gt;
						&amp;lt;/Expander&amp;gt;
					&amp;lt;/DataTemplate&amp;gt;
				&amp;lt;/ItemsControl.ItemTemplate&amp;gt;
			&amp;lt;/ItemsControl&amp;gt;
		&amp;lt;/ScrollViewer&amp;gt;

		&amp;lt;!-- Pracovni prostor --&amp;gt;
		&amp;lt;Grid Grid.Row="0"
				  Grid.Column="1"
				  Grid.ColumnSpan="2"&amp;gt;
			&amp;lt;Grid.ColumnDefinitions&amp;gt;
				&amp;lt;ColumnDefinition Width="100"/&amp;gt;
				&amp;lt;ColumnDefinition Width="*"/&amp;gt;
			&amp;lt;/Grid.ColumnDefinitions&amp;gt;
			
			&amp;lt;!-- Ovladaci tlacitka obsahu - Action Commands --&amp;gt;
			&amp;lt;ScrollViewer HorizontalScrollBarVisibility="Hidden"
						  VerticalScrollBarVisibility="Auto"&amp;gt;
				&amp;lt;ItemsControl ItemsSource="{Binding SelectedWorkspaceCommands}"
							  Background="#ff888888" 
							  BorderBrush="Black" 
							  BorderThickness="1,0,1,0"&amp;gt;
					&amp;lt;ItemsControl.ItemTemplate&amp;gt;
						&amp;lt;DataTemplate&amp;gt;
							&amp;lt;Button Command="{Binding}"
									HorizontalContentAlignment="Center" 
									VerticalContentAlignment="Center"
									Width="80" 
									Height="40"
									Margin="0,5,0,0"
									Content="{Binding Name}"&amp;gt;
							&amp;lt;/Button&amp;gt;
						&amp;lt;/DataTemplate&amp;gt;
					&amp;lt;/ItemsControl.ItemTemplate&amp;gt;
				&amp;lt;/ItemsControl&amp;gt;
			&amp;lt;/ScrollViewer&amp;gt;
			
			&amp;lt;!-- Finalni obsah - SelectedWorkspace --&amp;gt;
			&amp;lt;TabControl ItemsSource="{Binding Workspaces}" 
						Grid.Column="1"
						SelectedItem="{Binding SelectedWorkspace, Mode=TwoWay}"
						ItemTemplate="{StaticResource ClosableTabItemTemplate}"/&amp;gt;
		&amp;lt;/Grid&amp;gt;
	&amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;&lt;/pre&gt;
&lt;p&gt;XAML vypadá ve výsledku takhle:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_24.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_24.png" width="643" height="484"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hmm to nám toho moc neřekne, tak pojďmě si vytvořit nějaký model, který budeme moct použit už při návrhu a uvidíme, zda jsme všechny styly a bindingy nastavili správně.&lt;/p&gt;
&lt;p&gt;Pro tuto demonstraci si vytvoříme třídu DesignMainWindowViewModel, který bude dědit ze třídy MainWindowViewModel a DesignWorkspaceViewModel, která bude dědit ze třídy WorkspaceViewModel. Jediné co DesignMainWindowViewModel udělá je, že v konstruktoru naplní potřebné vlastnosti GroupCommands, Workspaces a SelectedWorkspace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DesignWorkspaceViewModel&lt;/strong&gt;&lt;/p&gt;&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;namespace MVVMSample.ViewModels
{
    internal class DesignWorkspaceViewModel : WorkspaceViewModel
    {
        public DesignWorkspaceViewModel()
        {
            
        }

        public DesignWorkspaceViewModel(string displayName)
        {
            DisplayName = displayName;
        }
    }
}&lt;/pre&gt;&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;DesignWorkspaceViewModel&lt;/strong&gt;&lt;/p&gt;&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;using System.Collections.Generic;
using MVVMSample.Commands;
using System.Windows;

namespace MVVMSample.ViewModels
{
    internal class DesignMainWindowViewModel : MainWindowViewModel
    {
        public DesignMainWindowViewModel()
        {
            GroupCommand moduleA =  new GroupCommand()
                {
                    GroupName = Shared.Strings.GroupCommand_ModuleA,
                    Commands = new List&amp;lt; RelayCommand &amp;gt;()
                        {
                            new UICommand(
                                execute =&amp;gt;
                                MessageBox.Show(Shared.Strings.Command_ViewModelA1))
                                {
                                    Name = Shared.Strings.Command_ViewModelA1
                                },
                            new UICommand(
                                execute =&amp;gt;
                                MessageBox.Show(Shared.Strings.Command_ViewModelA2))
                                {
                                    Name = Shared.Strings.Command_ViewModelA2
                                },
                            new UICommand(
                                execute =&amp;gt;
                                MessageBox.Show(Shared.Strings.Command_ViewModelA3))
                                {
                                    Name = Shared.Strings.Command_ViewModelA3
                                }
                        }
                };
            GroupCommand moduleB =  new GroupCommand()
                    {
                        GroupName = Shared.Strings.GroupCommand_ModuleB,
                        Commands = new List&amp;lt; RelayCommand &amp;gt;()
                            {
                                new UICommand(
                                    execute =&amp;gt;
                                    MessageBox.Show(Shared.Strings.Command_ViewModelB1))
                                    {
                                        Name = Shared.Strings.Command_ViewModelB1
                                    }
                            }
                    };
            GroupCommand moduleC = new GroupCommand()
                {
                    GroupName = Shared.Strings.GroupCommand_ModuleC,
                    Commands = new List&amp;lt; RelayCommand &amp;gt;()
                        {
                            new UICommand(
                                execute =&amp;gt;
                                MessageBox.Show(Shared.Strings.Command_ViewModelC1))
                                {
                                    Name = Shared.Strings.Command_ViewModelC1
                                }
                        }
                };
            GroupCommands = new List&amp;lt; GroupCommand &amp;gt;()
                {
                    moduleA,moduleB,moduleC
                };

            Workspaces.Add(new DesignWorkspaceViewModel("ViewModelA1"));
            Workspaces.Add(new DesignWorkspaceViewModel("ViewModelA2"));

            SelectedWorkspace = Workspaces[0];
        }
    }
}&lt;/pre&gt;
&lt;p&gt;Pokud tohle uděláme, můžeme dostat už v době návrhu docela dobrý feedback o našem návrhu.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_25.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_25.png" width="644" height="278"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Kromě vytvoření zmiňovaných tříd je zapotřebí v definici XAMLu nastavit, že se jako DataContext má nastavit právě náš DesignMainWindowViewModel&lt;/p&gt;&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;d:DataContext="{d:DesignInstance vm:DesignMainWindowViewModel, IsDesignTimeCreatable=True}"&lt;/pre&gt;
&lt;p&gt;Příště si už vytvoříme nějaký modul a ukážeme jak nastavit aby se pro ViewModel A zobrazilo View A apod.&lt;/p&gt;</description>
      <link>http://lukaskubis.net/post/MVVM-4e28093Shelle28093Design-Data.aspx</link>
      <author>lukask</author>
      <comments>http://lukaskubis.net/post/MVVM-4e28093Shelle28093Design-Data.aspx#comment</comments>
      <guid>http://lukaskubis.net/post.aspx?id=64d62368-7554-4da3-a533-e36b62d65b24</guid>
      <pubDate>Thu, 03 Mar 2011 12:33:03 +1000</pubDate>
      <dc:publisher>lukask</dc:publisher>
      <pingback:server>http://lukaskubis.net/pingback.axd</pingback:server>
      <pingback:target>http://lukaskubis.net/post.aspx?id=64d62368-7554-4da3-a533-e36b62d65b24</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://lukaskubis.net/trackback.axd?id=64d62368-7554-4da3-a533-e36b62d65b24</trackback:ping>
      <wfw:comment>http://lukaskubis.net/post/MVVM-4e28093Shelle28093Design-Data.aspx#comment</wfw:comment>
      <wfw:commentRss>http://lukaskubis.net/syndication.axd?post=64d62368-7554-4da3-a533-e36b62d65b24</wfw:commentRss>
    </item>
    <item>
      <title>MVVM #3–Shell</title>
      <description>&lt;p&gt;Předchozí díly:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://lukaskubis.net/post/MVVM-1e28093Uvod.aspx"&gt;MVVM #1–Úvod&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://lukaskubis.net/post/MVVM-2e28093Priprava.aspx"&gt;MVVM #2–Příprava&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Jestli vzpomínáte na předchozí díl, byl tam návrh naší aplikace, která se skládala z navigačního menu (GroupCommands), pracovního prostoru (Workspace) a nějakých “akčních” tlačítek.&lt;/p&gt;  &lt;p&gt;Co by tedy naše navigačního menu (GroupCommands) mělo obsahovat? Měl by stačit pouze nějaký název a kolekce Commandů, kde každý Command vytvoří novou záložku. Prostě když si kliknu v navigačním menu na nějakou možnost, vytvoří se mi nová záložka a v pracovním prostoru se zobrazí příslušné data.&lt;/p&gt;  &lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;/// &amp;lt;summary&amp;gt;
/// Trida reprezentujici leve menu
/// &amp;lt;/summary&amp;gt;
public sealed class GroupCommand
{
    /// &amp;lt;summary&amp;gt;
    /// Nazev skupiny
    /// &amp;lt;/summary&amp;gt;
    public string GroupName { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Prikazy ktere se provedou po stisku navigacnich tlacitek
    /// &amp;lt;/summary&amp;gt;
    public List&amp;lt;RelayCommand&amp;gt; Commands { get; set; }
}&lt;/pre&gt;

&lt;p&gt;GroupCommand jsme si definovali, ale je třeba vytvořit hlavní ViewModel, který bude mít na starost:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;zobrazení navigačního menu &lt;/li&gt;

  &lt;li&gt;zobrazení dat v pracovním prostoru &lt;/li&gt;

  &lt;li&gt;vytváření nový záložek &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vytvořme si tedy MainWindowViewModel:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_23.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_23.png" width="640" height="420" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jak si můžete všimnout na obrázku výše, budeme potřebovat pouze kolekci GroupCommands (navigační menu), Workspaces (jednotlivé záložky), SelectedWorkspace (aktuální záložka) a SelectedWorkspaceCommands (“akční&amp;quot; tlačítka). Dále jsou zde ještě metody pro vytvoření či odebrání záložky a pro vytvoření obsluhy žádosti o uzavření záložky.&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class MainWindowViewModel : ViewModelBase
{
    #region | Fields

    private ObservableCollection&amp;lt;WorkspaceViewModel&amp;gt; _workspaces;
    private WorkspaceViewModel _selectedWorkspace;

    #endregion // Fields

    #region | Commands

    /// &amp;lt;summary&amp;gt;
    /// Leve menu
    /// &amp;lt;/summary&amp;gt;
    public List&amp;lt;GroupCommand&amp;gt; GroupCommands { get; set; }

    public List&amp;lt;RelayCommand&amp;gt; SelectedWorkspaceCommands
    {
        get
        {
            // pokud neni oznacen workspace vrat prazdnou kolekci
            if ( SelectedWorkspace == null )
                return new List&amp;lt;RelayCommand&amp;gt;();

            return SelectedWorkspace.Commands;
        }
    }

    #endregion // Commands

    #region | Workspaces

    /// &amp;lt;summary&amp;gt;
    /// Aktualni seznam Workspace-u
    /// &amp;lt;/summary&amp;gt;
    public ObservableCollection&amp;lt;WorkspaceViewModel&amp;gt; Workspaces
    {
        get
        {
            if ( _workspaces == null )
            {
                _workspaces = new ObservableCollection&amp;lt;WorkspaceViewModel&amp;gt;();
                _workspaces.CollectionChanged += this.OnWorkspacesChanged;
            }
            return _workspaces;
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Aktualne vybrany Workspace
    /// &amp;lt;/summary&amp;gt;
    public WorkspaceViewModel SelectedWorkspace
    {
        get { return _selectedWorkspace; }
        set
        {
            if ( _selectedWorkspace == value )
                return;

            _selectedWorkspace = value;

            // posli notifikaci o zmene vlastnosti SelectedWorkspace
            OnPropertyChanged(MethodBase.GetCurrentMethod());
            OnPropertyChanged(&amp;quot;SelectedWorkspaceCommands&amp;quot;);
        }
    }

    #endregion // Workspaces

    #region | OnWorkspacesChanged

    /// &amp;lt;summary&amp;gt;
    /// Obsluha udalosti ObservableCollection(WorkspaceViewModelEx).CollectionChanged
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;sender&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;e&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // pri zmene workspace vytvorim obsluhu udalosti RequestClose

        if ( e.NewItems != null &amp;amp;&amp;amp; e.NewItems.Count != 0 )
            foreach ( WorkspaceViewModel workspace in e.NewItems )
                workspace.RequestClose += this.OnWorkspaceRequestClose;

        if ( e.OldItems != null &amp;amp;&amp;amp; e.OldItems.Count != 0 )
            foreach ( WorkspaceViewModel workspace in e.OldItems )
                workspace.RequestClose -= this.OnWorkspaceRequestClose;
    }

    #endregion // OnWorkspacesChanged

    #region | OnWorkspaceRequestClose

    /// &amp;lt;summary&amp;gt;
    /// Obsluha udalosti WorkspaceViewModel.RequestClose
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;sender&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;e&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    void OnWorkspaceRequestClose(object sender, EventArgs e)
    {
        // odeberu uzavreny workspace
        Workspaces.Remove(sender as WorkspaceViewModel);
    }

    #endregion // OnWorkspaceRequestClose

    #region | AddWorkspace

    /// &amp;lt;summary&amp;gt;
    /// Prida workspace do seznamu workspace-u
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;workspaceViewModel&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    public void AddWorkspace(WorkspaceViewModel workspaceViewModel)
    {
        Workspaces.Add(workspaceViewModel);
        SelectedWorkspace = workspaceViewModel;
    }

    #endregion // AddWorkspace
}&lt;/pre&gt;

&lt;p&gt;Tak už máme MainWindowViewModel, ale nemáme k němu příslušné View. To ovšem napravíme příště.&lt;/p&gt;</description>
      <link>http://lukaskubis.net/post/MVVM-3e28093Shell.aspx</link>
      <author>lukask</author>
      <comments>http://lukaskubis.net/post/MVVM-3e28093Shell.aspx#comment</comments>
      <guid>http://lukaskubis.net/post.aspx?id=58221be8-3c9c-41b7-8476-21635074ee71</guid>
      <pubDate>Mon, 21 Feb 2011 07:06:25 +1000</pubDate>
      <dc:publisher>lukask</dc:publisher>
      <pingback:server>http://lukaskubis.net/pingback.axd</pingback:server>
      <pingback:target>http://lukaskubis.net/post.aspx?id=58221be8-3c9c-41b7-8476-21635074ee71</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://lukaskubis.net/trackback.axd?id=58221be8-3c9c-41b7-8476-21635074ee71</trackback:ping>
      <wfw:comment>http://lukaskubis.net/post/MVVM-3e28093Shell.aspx#comment</wfw:comment>
      <wfw:commentRss>http://lukaskubis.net/syndication.axd?post=58221be8-3c9c-41b7-8476-21635074ee71</wfw:commentRss>
    </item>
    <item>
      <title>MVVM #2–Příprava</title>
      <description>&lt;p&gt;Předchozí díly:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://lukaskubis.net/post/MVVM-1e28093Uvod.aspx" target="_blank"&gt;MVVM #1 – Úvod&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;V minulém díle jsme si ukázali obrázek architektury a dnes se podíváme na základní layout naší aplikace&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_20.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_20.png" width="641" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Úplně v levé části bude navigační menu. Navigační menu bude sloužit pro spouštění akcí jednotlivých modulů. Vedle navigační menu, je prostor pro tzv. “akční” tlačítka. Bude se jednat o tlačítka, která budou provádět nějakou akci pro zrovna zobrazené data. A na opačné pravé straně bude prostor pro zobrazení potřebných dat. Tento prostor bude dále členěn na jednotlivé záložky tak jak to je např. v Internet Exploreru.&lt;/p&gt;  &lt;h2&gt;ViewModels&lt;/h2&gt;  &lt;p&gt;Nejdříve si připravíme základní ViewModel-y:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_21.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_21.png" width="232" height="265" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;ViewModelBase bude obsahovat pouze to nejdůležitější:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;DisplayName – Název ViewModelu, který se zobrazí na záložce. &lt;/li&gt;    &lt;li&gt;Tag – vlastnost pro doplňující informace &lt;/li&gt;    &lt;li&gt;IPropertyChanged – Implementace tohoto rozhraní nám umožní při použití Bindingu notifikovat o změně hodnoty příslušné vlastnosti. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Kód vypadá následně:&lt;/p&gt;  &lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
{
    #region | Properties

    #region | DisplayName
    private string _displayName;
    public string DisplayName
    {
        get { return _displayName; }
        protected set
        {
            _displayName = value;
            OnPropertyChanged(MethodBase.GetCurrentMethod());
        }
    }

    #endregion // DisplayName

    #region | Tag
    private string _tag;
    public string Tag
    {
        get { return _tag; }
        protected set
        {
            _tag = value;
            OnPropertyChanged(MethodBase.GetCurrentMethod());
        }
    }
    #endregion // Tag

    #region | Ctor

    protected ViewModelBase()
    {
    }

    #endregion // Ctor

    #endregion // Properties

    #region | Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    /// &amp;lt;summary&amp;gt;
    /// Notifikuje UI o zmene vlastnosti
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;methodBase&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    protected virtual void OnPropertyChanged(MethodBase methodBase)
    {
        this.OnPropertyChanged(methodBase.Name.Substring(4));
    }

    /// &amp;lt;summary&amp;gt;
    /// Notifikuje UI o zmene vlastnosti
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;propertyName&amp;quot;&amp;gt;Zmemena vlastnost&amp;lt;/param&amp;gt;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if ( handler != null )
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion // Implementation of INotifyPropertyChanged

    #region | Implementation of IDisposable

    /// &amp;lt;summary&amp;gt;
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;filterpriority&amp;gt;2&amp;lt;/filterpriority&amp;gt;
    public void Dispose()
    {
        this.OnDispose();
    }

    /// &amp;lt;summary&amp;gt;
    /// Potomci zde muzou provest &amp;quot;uklid&amp;quot; kodu - odebrani handleru, apod.
    /// &amp;lt;/summary&amp;gt;
    protected virtual void OnDispose()
    {
    }

    #endregion // Implementation of IDisposable

    #region | Debug

#if DEBUG
    ~ViewModelBase()
    {
        string msg = string.Format(&amp;quot;{0} ({1}) ({2}) Finalized&amp;quot;, this.GetType().Name, this.DisplayName, this.GetHashCode());
        System.Diagnostics.Debug.WriteLine(msg);

    }
#endif
    #endregion // Debug
}&lt;/pre&gt;

&lt;p&gt;WorkspaceViewModel bude reprezentovat konkrétní záložku:&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;/// &amp;lt;summary&amp;gt;
/// Trida reprezentujici workspace - zobrazuje se jako zalozka
/// &amp;lt;/summary&amp;gt;
public abstract class WorkspaceViewModel : ViewModelBase
{
    #region | Fields

    private RelayCommand _refreshCommand;
    private RelayCommand _closeCommand;

    #endregion // Fields

    #region | Commands

    /// &amp;lt;summary&amp;gt;
    /// Vrati kolekci Commandu, ktere budou dostupne v levem menu. K jednotlivym
    /// Commandum se pripoji jeden pro Refresh dat
    /// &amp;lt;/summary&amp;gt;
    public List&amp;lt;RelayCommand&amp;gt; Commands
    {
        get
        {
            List&amp;lt;RelayCommand&amp;gt; cmds = new List&amp;lt;RelayCommand&amp;gt;()
            {
                RefreshCommand 
            };
            cmds.AddRange(OnCreateCommands());

            return cmds;
        }
    }

    protected virtual RelayCommand RefreshCommand
    {
        get
        {
            if ( _refreshCommand == null )
                _refreshCommand = new UICommand(param =&amp;gt; Refresh())
                {
                    Name = Strings.Command_Refresh,
                };

            return _refreshCommand;
        }
    }

    public RelayCommand CloseCommand
    {
        get
        {
            if ( _closeCommand == null )
                _closeCommand = new UICommand(param =&amp;gt; Close())
                {
                    Name = &amp;quot;x&amp;quot;
                };

            return _closeCommand;
        }
    }

    #endregion // Commands

    #region | Virtual Methods

    #region | CreateCommands

    /// &amp;lt;summary&amp;gt;
    /// Potomci si napisou vlastni implementaci
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    protected virtual List&amp;lt;RelayCommand&amp;gt; OnCreateCommands()
    {
        return new List&amp;lt;RelayCommand&amp;gt;();
    }

    public List&amp;lt;RelayCommand&amp;gt; CreateCommands()
    {
        return OnCreateCommands();
    }

    #endregion // CreateCommands

    #region | Initialize

    /// &amp;lt;summary&amp;gt;
    /// Potomci provedou vlastni obsluhu inicializacni metody
    /// &amp;lt;/summary&amp;gt;
    protected virtual void OnInitialize()
    {
        // slouzi pro aktualizaci dat ve ViewModelu
    }

    public void Initialize()
    {
        this.OnInitialize();
    }

    #endregion // Initialize

    #region | Close

    public void Close()
    {
        this.OnRequestClose();
    }

    #endregion // Close

    #endregion // Virtual Methods

    #region | Overrides

    protected override void OnDispose()
    {
    }

    #endregion // Overrides

    #region | Private Methods

    #region | Refresh

    /// &amp;lt;summary&amp;gt;
    /// Provede aktualizaci  dat ve ViewModelu
    /// &amp;lt;/summary&amp;gt;
    void Refresh()
    {
        this.OnInitialize();
    }

    #endregion // Refresh

    #region | OnRequestClose

    /// &amp;lt;summary&amp;gt;
    /// Vyvola udalost na uzavreni Workspace-u
    /// &amp;lt;/summary&amp;gt;
    void OnRequestClose()
    {
        var handler = RequestClose;
        if ( handler != null )
            handler(this, EventArgs.Empty);
    }

    #endregion // OnRequestClose

    #endregion // Private NMethods

    #region | Events

    /// &amp;lt;summary&amp;gt;
    /// Udalost uzavreni workspace-u
    /// &amp;lt;/summary&amp;gt;
    public event EventHandler RequestClose;

    #endregion // Events
}&lt;/pre&gt;

&lt;p&gt;WorkspaceViewModel obsahuje dva commandy, jeden pro uzavření workspace-u (Close) a druhý po aktualizaci dat (Refresh). Dále zde máme metodu CreateCommands, která vrátí vždy příslušné Commandy (Action Commands), které jsou dostupné v rámci každé záložky.&lt;/p&gt;

&lt;h2&gt;Commands&lt;/h2&gt;

&lt;p&gt;Jak jste si mohli všimnout tak ve třídě WorkspaceViewModel využíváme třídu RelayCommand a UICommand o které jsme předtím nemluvili. Nyní na to máme prostor.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_22.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_22.png" width="237" height="240" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Třída UICommand obsahuje pouze název commandu, delegát pro vykonání akce a podmínku, za které lze akci spustit.&lt;/p&gt;

&lt;p&gt;RelayCommand&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public abstract class RelayCommand : ICommand
{
    #region | Fields

    private readonly Action&amp;lt; object &amp;gt; _execute;
    private readonly Predicate&amp;lt; object &amp;gt; _canExecute;

    #endregion // Fields

    #region | Constructors

    /// &amp;lt;summary&amp;gt;
    /// Creates a new command that can always execute.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;execute&amp;quot;&amp;gt;The execution logic.&amp;lt;/param&amp;gt;
    protected RelayCommand(Action&amp;lt;object&amp;gt; execute)
        : this(execute, null)
    {
    }

    /// &amp;lt;summary&amp;gt;
    /// Creates a new command.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;execute&amp;quot;&amp;gt;The execution logic.&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;canExecute&amp;quot;&amp;gt;The execution status logic.&amp;lt;/param&amp;gt;
    protected RelayCommand(Action&amp;lt;object&amp;gt; execute, Predicate&amp;lt;object&amp;gt; canExecute)
    {
        if ( execute == null )
            throw new ArgumentNullException(&amp;quot;execute&amp;quot;);

        _execute = execute;
        _canExecute = canExecute;
    }

    #endregion

    #region | ICommand members

    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public virtual void Execute(object parameter)
    {
        if ( CanExecute(parameter) )
        {
            _execute(parameter);
        }
    }

    #endregion // ICommand Members

    #region | Properties

    /// &amp;lt;summary&amp;gt;
    /// Nazev Commandu - zobrazi se na tlacitku
    /// &amp;lt;/summary&amp;gt;
    public string Name { get; set; }

    #endregion // Properties
}&lt;/pre&gt;

&lt;p&gt;A UICommand&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;/// &amp;lt;summary&amp;gt;
/// Spusti command na UI vlakne
/// &amp;lt;/summary&amp;gt;
public class UICommand : RelayCommand
{
    public UICommand(Action&amp;lt;object&amp;gt; execute)
        : base(execute)
    {
    }

    public UICommand(Action&amp;lt;object&amp;gt; execute, Predicate&amp;lt;object&amp;gt; canExecute)
        : base(execute, canExecute)
    {
    }
}&lt;/pre&gt;

&lt;p&gt;Příště si vytvoříme hlavní aplikaci (MVVMSample.Shell) kde bude MainWindowViewModel, který bude představovat naše hlavní okno aplikace. Jakmile si připravíme tohle tak pak začneme vytvářet jednotlivé moduly a skládat vše dokupy.&lt;/p&gt;</description>
      <link>http://lukaskubis.net/post/MVVM-2e28093Priprava.aspx</link>
      <author>lukask</author>
      <comments>http://lukaskubis.net/post/MVVM-2e28093Priprava.aspx#comment</comments>
      <guid>http://lukaskubis.net/post.aspx?id=8103e62b-0f3f-4584-bff6-72646230c4ee</guid>
      <pubDate>Sun, 13 Feb 2011 07:17:13 +1000</pubDate>
      <dc:publisher>lukask</dc:publisher>
      <pingback:server>http://lukaskubis.net/pingback.axd</pingback:server>
      <pingback:target>http://lukaskubis.net/post.aspx?id=8103e62b-0f3f-4584-bff6-72646230c4ee</pingback:target>
      <slash:comments>5</slash:comments>
      <trackback:ping>http://lukaskubis.net/trackback.axd?id=8103e62b-0f3f-4584-bff6-72646230c4ee</trackback:ping>
      <wfw:comment>http://lukaskubis.net/post/MVVM-2e28093Priprava.aspx#comment</wfw:comment>
      <wfw:commentRss>http://lukaskubis.net/syndication.axd?post=8103e62b-0f3f-4584-bff6-72646230c4ee</wfw:commentRss>
    </item>
    <item>
      <title>MVVM #1–Úvod</title>
      <description>&lt;p&gt;Nedávno jsem vyvíjel jednu aplikaci, která mě inspirovala k napsání následujících článků. Bude se jednat především o použití MVVM ve WPF aplikaci, ale pokusím se zde zahrnout i věci týkající se MEFu, Expression Blendu, či něčeho jiného co mi příjde zajímavé.&lt;/p&gt;  &lt;p&gt;Pro ukázku si poskládáme jednoduchou WPF aplikaci od základů až po různá vylepšení. Tato aplikace bude takovou odlehčenou verzi té původní, která mě inspirovala pro tento “seriál”. Na obrázku níže můžete vidět architekturu naší aplikace.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_19.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_19.png" width="644" height="250" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Aplikace se skládá z několika částí:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;MVVMSample.Shell – Výsledná aplikace (exe), která po spuštění nabídne funkcionalitu jednotlivých modulů &lt;/li&gt;    &lt;li&gt;MVVMSample.Shared – sdílená knihovna – obsahuje různé pomocné metody, společné třídy apod. &lt;/li&gt;    &lt;li&gt;MVVMSample.ModuleA-C – jednotlivé moduly, kde každý modul představuje jednoduchou funkcionalitu &lt;/li&gt; &lt;/ul&gt;</description>
      <link>http://lukaskubis.net/post/MVVM-1e28093Uvod.aspx</link>
      <author>lukask</author>
      <comments>http://lukaskubis.net/post/MVVM-1e28093Uvod.aspx#comment</comments>
      <guid>http://lukaskubis.net/post.aspx?id=9c595a8c-ed56-48d4-baa0-ea3875a3c2cd</guid>
      <pubDate>Sun, 13 Feb 2011 07:15:39 +1000</pubDate>
      <dc:publisher>lukask</dc:publisher>
      <pingback:server>http://lukaskubis.net/pingback.axd</pingback:server>
      <pingback:target>http://lukaskubis.net/post.aspx?id=9c595a8c-ed56-48d4-baa0-ea3875a3c2cd</pingback:target>
      <slash:comments>6</slash:comments>
      <trackback:ping>http://lukaskubis.net/trackback.axd?id=9c595a8c-ed56-48d4-baa0-ea3875a3c2cd</trackback:ping>
      <wfw:comment>http://lukaskubis.net/post/MVVM-1e28093Uvod.aspx#comment</wfw:comment>
      <wfw:commentRss>http://lukaskubis.net/syndication.axd?post=9c595a8c-ed56-48d4-baa0-ea3875a3c2cd</wfw:commentRss>
    </item>
    <item>
      <title>Windows Phone 7–jak na orientaci</title>
      <description>&lt;p&gt;Vítejte u druhého dílu ze seriálu o vývoji pod WP7. Předchozí díl najdete na:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://lukaskubis.net/post/Windows-Phone-7-zaciname.aspx" target="_blank"&gt;Windows Phone 7 – začínáme&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Dnes se ve velice krátké ukázce podíváme na možnosti orintace telefonu. Jak umožnit zobrazovat obsah v “portrait” nebo “landscape” módu, jak reagovat na události změny orientace ,apod.&lt;/p&gt;  &lt;p&gt;Defaultně se aplikace spouštějí v tzv. “portrait” módu:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_15.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_15.png" width="133" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;a pokud otočíme telefonem o 90° dostaneme se do tzv. “landscape” módu&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_16.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_16.png" width="244" height="132" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Bohužel jak si můžete všimnout tak v landscape módu naše aplikace nevypadá zrovna nejlíp. To je způsobeno nastavením vlastnosti SupportedOrientations přímo v xamlu&lt;/p&gt;  &lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;SupportedOrientations=&amp;quot;Portrait&amp;quot;&lt;/pre&gt;

&lt;p&gt;Tato vlastnost může nabývat těchto hodnot:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Portrait &lt;/li&gt;

  &lt;li&gt;Landscape &lt;/li&gt;

  &lt;li&gt;PortraitOrLandscape &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pokud vybereme poslední možnost PortraitOrLandscape, tak při natočení telefonu, se rovněž změní i layout aplikace&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_17.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_17.png" width="244" height="131" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Víme co je nutné nastavit, aby byly podporovány oba módy zobrazení, ale jak např. zareagovat na změnu orientace. Představte si, že napíšete aplikaci, která může pracovat v obou módech a v závislosti na móodu se bude UI přizpůsobovat.&lt;/p&gt;

&lt;p&gt;Třída PhoneApplicationBase obsahuje virtuální metodu OnOrientationChanged, kterou můžeme přepsat a tak jednoduše reagovat na změnu orientace.&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public partial class MainPage : PhoneApplicationPage
{
    // Constructor
    public MainPage()
    {
        InitializeComponent();

        txt.Text = &amp;quot;Orientation: &amp;quot; + Orientation.ToString();
    }

    protected override void OnOrientationChanged(OrientationChangedEventArgs args)
    {
        txt.Text = &amp;quot;Orientation: &amp;quot; + Orientation.ToString();
        base.OnOrientationChanged(args);
    }
}&lt;/pre&gt;

&lt;p&gt;Vlastnost Orientation je typu PageOrientation a může nabývat následujících hodnot:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Landscape &lt;/li&gt;

  &lt;li&gt;LandscapeLeft &lt;/li&gt;

  &lt;li&gt;LandscapeRight &lt;/li&gt;

  &lt;li&gt;None &lt;/li&gt;

  &lt;li&gt;Portrait &lt;/li&gt;

  &lt;li&gt;PortraitDown &lt;/li&gt;

  &lt;li&gt;PortraitUp &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_18.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_18.png" width="244" height="130" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Naviděnou u dalšího dílu&lt;/p&gt;</description>
      <link>http://lukaskubis.net/post/Windows-Phone-7e28093jak-na-orientaci.aspx</link>
      <author>lukask</author>
      <comments>http://lukaskubis.net/post/Windows-Phone-7e28093jak-na-orientaci.aspx#comment</comments>
      <guid>http://lukaskubis.net/post.aspx?id=c11a8485-3afd-4896-94c9-f9fd7162e09c</guid>
      <pubDate>Wed, 29 Dec 2010 09:19:30 +1000</pubDate>
      <dc:publisher>lukask</dc:publisher>
      <pingback:server>http://lukaskubis.net/pingback.axd</pingback:server>
      <pingback:target>http://lukaskubis.net/post.aspx?id=c11a8485-3afd-4896-94c9-f9fd7162e09c</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://lukaskubis.net/trackback.axd?id=c11a8485-3afd-4896-94c9-f9fd7162e09c</trackback:ping>
      <wfw:comment>http://lukaskubis.net/post/Windows-Phone-7e28093jak-na-orientaci.aspx#comment</wfw:comment>
      <wfw:commentRss>http://lukaskubis.net/syndication.axd?post=c11a8485-3afd-4896-94c9-f9fd7162e09c</wfw:commentRss>
    </item>
    <item>
      <title>Silverlight 4 - Kurzovní lístek – krok za krokem</title>
      <description>&lt;p&gt;V dnešním článku si vytvoříme jednoduchou aplikaci, která bude zobrazovat aktuální kurzovní lístek. Tuto aplikaci si pak budete moci umístit např. na Vaše vlastní stránky.&lt;/p&gt;  &lt;h2&gt;1. krok – Návrh aplikace&lt;/h2&gt;  &lt;p&gt;Jako zdroj dat budeme využívat kurzovní lístek Československé obchodní banky, a.s. (ČSOB), který najdeme k dispozici ve formátu txt na adrese &lt;a href="http://www.csob.cz/webcsob/kurzy/kurzynewcz.txt"&gt;http://www.csob.cz/webcsob/kurzy/kurzynewcz.txt&lt;/a&gt;. Struktura souboru vypadá následovně:&lt;/p&gt;  &lt;pre class="brush: text; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;2010-12-23 17:20:00

;;;;Devizy;;;Valuty
Země;Množství;Měna;Změna;Nákup;Prodej;Střed;Nákup;Prodej;Střed
Austrálie;1;AUD;0,80;18,953;19,687;19,320;0,00;0,00;0,00
Dánsko;1;DKK;0,20;3,330;3,460;3,395;3,32;3,46;3,39
EMS;1;EUR;0,20;24,817;25,779;25,298;24,77;25,83;25,30
Chorvatsko;1;HRK;0,10;3,358;3,488;3,423;0,00;0,00;0,00
Japonsko;100;JPY;1,20;22,744;23,672;23,208;0,00;0,00;0,00
Kanada;1;CAD;0,80;18,697;19,421;19,059;0,00;0,00;0,00
Maďarsko;100;HUF;0,50;8,976;9,342;9,159;0,00;0,00;0,00
Norsko;1;NOK;0,10;3,162;3,284;3,223;3,15;3,29;3,22
Polsko;1;PLN;0,50;6,217;6,471;6,344;0,00;0,00;0,00
Rumunsko;1;RON;0,30;5,789;6,025;5,907;0,00;0,00;0,00
Rusko;100;RUB;0,70;61,783;64,177;62,980;0,00;0,00;0,00
Švédsko;1;SEK;0,00;2,762;2,870;2,816;2,76;2,88;2,82
Švýcarsko;1;CHF;1,00;19,883;20,653;20,268;19,84;20,70;20,27
Turecko;1;TRY;0,70;12,199;12,671;12,435;0,00;0,00;0,00
USA;1;USD;0,40;18,908;19,680;19,294;18,87;19,71;19,29
Velká Británie;1;GBP;0,00;29,154;30,344;29,749;29,10;30,40;29,75&lt;/pre&gt;

&lt;p&gt;Vytvoříme si třídu, která bude reprezentovat aktuální kurz:&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;/// &amp;lt;summary&amp;gt;
/// Kurz
/// &amp;lt;/summary&amp;gt;
public class ExchangeRate
{
    /// &amp;lt;summary&amp;gt;
    /// Měna
    /// &amp;lt;/summary&amp;gt;
    public string Currency { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Země
    /// &amp;lt;/summary&amp;gt;
    public string Country { get; set; }
        
    /// &amp;lt;summary&amp;gt;
    /// Množství
    /// &amp;lt;/summary&amp;gt;
    public int Amount { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Změna
    /// &amp;lt;/summary&amp;gt;
    public float Change { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Devizy - nákup
    /// &amp;lt;/summary&amp;gt;
    public float PurchaseCashless { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Devizy - prodej
    /// &amp;lt;/summary&amp;gt;
    public float SalesCashless { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Devizy - střed
    /// &amp;lt;/summary&amp;gt;
    public float MidPointCashless { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Valuty - nákup
    /// &amp;lt;/summary&amp;gt;
    public float PurchaseCash { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Valuty - prodej
    /// &amp;lt;/summary&amp;gt;
    public float SalesCash { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Valuty - střed
    /// &amp;lt;/summary&amp;gt;
    public float MidPointCash { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Graf
    /// &amp;lt;/summary&amp;gt;
    public string Chart { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Máme třídu reprezentující konkrétní kurz a ještě si vytvoříme třídu, která bude obsahovat až n-kurzů&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;/// &amp;lt;summary&amp;gt;
/// Kurzy
/// &amp;lt;/summary&amp;gt;
public class ExchangeRates
{
    /// &amp;lt;summary&amp;gt;
    /// Seznam jednotlivych kurzu
    /// &amp;lt;/summary&amp;gt;
    public ObservableCollection&amp;lt;ExchangeRate&amp;gt; Data { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Máme data, potřebné třídy a tak už jenom stačí data stáhnout, inicializovat třídy a nějak pěkně zobrazit.&lt;/p&gt;

&lt;h2&gt;2. krok – Vytvoření WCF služby pro stažení dat z internetu&lt;/h2&gt;

&lt;p&gt;Pro stažení dat využijeme WCF službu, kde pomocí třídy WebClient a metody DownloadStringAsync stáhneme kurzovní lístek.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Poznámka: Jelikož server csob.cz neobsahuje potřebný soubor(y) crossdomain.xml a clientaccesspolicy.xml využívám pro stažení WCF službu. Kdybych použil WebClient.DownloadStringAsync přímo ze Silverlightu, dostal bych vždy SecurityException. Více o bezpečnostních omezeních najdete v článku &lt;/em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc645032(v=vs.95).aspx" target="_blank"&gt;&lt;em&gt;Network Security Access Restrictions in Silverlight&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WCF služba bude obsahovat pouze jednu metodu nazvanou GetData, která vrátí obsah kurzovního lístku. &lt;strong&gt;POZOR !!!tato WCF služba je umístěna ve webové aplikaci, ve které spuštíme silverlight aplikaci.&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;[ServiceContract]
public interface IExchangeRatesService
{
    [OperationContract]
    string GetData();
}

public class ExchangeRatesService : IExchangeRatesService
{
    public string GetData()
    {
        string data = null;
        using ( WebClient client = new WebClient() )
        {
            try
            {
                data = client.DownloadString(@&amp;quot;http://www.csob.cz/webcsob/kurzy/kurzynewcz.txt&amp;quot;);
            }
            catch ( Exception ex )
            {
                data = ex.Message;
            }
        }
        return data;
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Poznámka: Url adresa kurzovního lístku je zde napevno, což není nejlepší řešení, takže bych spíše doporučil tuto adresu předávat jako parametr metody GetData. V naší ukázce to ale ničemu vadit nebude.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Upravíme ještě nastavení služby ve web.config-u&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;system.serviceModel&amp;gt;
    &amp;lt;services&amp;gt;
      &amp;lt;service name=&amp;quot;ExchangeRatesSample.Web.ExchangeRatesService&amp;quot;&amp;gt;
        &amp;lt;endpoint address=&amp;quot;&amp;quot;
                  binding=&amp;quot;basicHttpBinding&amp;quot;
                  contract=&amp;quot;ExchangeRatesSample.Web.IExchangeRatesService&amp;quot;&amp;gt;
        &amp;lt;/endpoint&amp;gt;
      &amp;lt;/service&amp;gt;
    &amp;lt;/services&amp;gt;
      &amp;lt;behaviors&amp;gt;
          &amp;lt;serviceBehaviors&amp;gt;
              &amp;lt;behavior&amp;gt;
                  &amp;lt;serviceMetadata httpGetEnabled=&amp;quot;true&amp;quot; /&amp;gt;
                  &amp;lt;serviceDebug includeExceptionDetailInFaults=&amp;quot;true&amp;quot; /&amp;gt;
              &amp;lt;/behavior&amp;gt;
          &amp;lt;/serviceBehaviors&amp;gt;
      &amp;lt;/behaviors&amp;gt;
      &amp;lt;serviceHostingEnvironment multipleSiteBindingsEnabled=&amp;quot;true&amp;quot; /&amp;gt;
  &amp;lt;/system.serviceModel&amp;gt;&lt;/pre&gt;

&lt;h2&gt;3. krok – Stažení dat pomocí WCF služby&lt;/h2&gt;

&lt;p&gt;V silverlight aplikaci přidáme referenci na WCF službu kliknutím pravým na References a vybráním volby “Add Service Reference”. Jakmile přidáme referenci, tak si otevřeme kód na pozadí MainPagexaml.cs a obsloužíme událost Loaded.&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
        this.Loaded += MainPageOnLoaded;
    }

    void MainPageOnLoaded(object sender, RoutedEventArgs args)
    {
        var proxy = new ExchangeRatesServiceClient();
        proxy.GetDataCompleted += GetDataOnCompleted;
        proxy.GetDataAsync();
    }

    void GetDataOnCompleted(object sender, GetDataCompletedEventArgs args)
    {
        if ( args.Error == null &amp;amp;&amp;amp; !args.Cancelled )
        {
            var rates = new ExchangeRates();
            rates.Data = new ObservableCollection&amp;lt; ExchangeRate &amp;gt;();
                
            var lines = from l in args.Result.Split('\r', '\n').Skip(8)
                        where !string.IsNullOrWhiteSpace(l)
                        select l;

            foreach ( var line in lines ) 
            {
                var rate = ExchangeRate.FromLine(line);
                if ( rate != null )
                    rates.Data.Add(rate);
            }
        }
    }
}&lt;/pre&gt;

&lt;p&gt;Třída &lt;strong&gt;ExchangeRatesServiceClient&lt;/strong&gt; se mi vygenerovala, když jsem přidal referenci na WCF službu. V metodě &lt;strong&gt;GetDataOnCompleted&lt;/strong&gt; si ziskám pouze ty řádky, na kterých jsou kurzy a převedu je na objekty typu &lt;strong&gt;ExchangeRate&lt;/strong&gt; pomocí pomocné statické metody FromLine&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public static ExchangeRate FromLine(string line)
{
    var data = line.Split(';');

    return new ExchangeRate()
    {
        Country = data[0],
        Amount = int.Parse(data[1]),
        Currency = data[2],
        Change = float.Parse(data[3]),
        PurchaseCashless = float.Parse(data[4]),
        SalesCashless = float.Parse(data[5]),
        MidPointCashless = float.Parse(data[6]),
        PurchaseCash = float.Parse(data[7]),
        SalesCash = float.Parse(data[8]),
        MidPointCash = float.Parse(data[9])
    };
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;4. krok – Zobrazení dat v DataGridu&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Přidáme si do MainPage DataGrid&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt; &amp;lt;data:DataGrid Grid.Row=&amp;quot;1&amp;quot; ItemsSource=&amp;quot;{Binding Data}&amp;quot; 
                AutoGenerateColumns=&amp;quot;True&amp;quot;/&amp;gt;&lt;/pre&gt;

&lt;p&gt;kde &lt;strong&gt;data&lt;/strong&gt; je definice namespace ve kterém se DataGrid nachází (xmlns:data=&amp;quot;clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data&amp;quot;). No a pak už jenom stačí za cyklem foreach nastavit DataContext na nově vytvořený objekt rates, který ve vlastnosti Data uchovává veškeré kurzy. Po spuštění může aplikace vypadat takto:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_9.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_9.png" width="244" height="120" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Krok – Úprava hlavičky DataGridu&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aplikace funguje – data se stáhnou, zobrazí, ale není to ještě úplně ono. Např. některé sloupce jsou zde uvedeny 2x - prodej, nákup a střed. První trojice je pro Devizy a druhá pro Valuty, ale zatím to poznám pouze já. Upravíme tedy hlavičku našeho gridu tak, aby měla “2 řádky”. Druhý řádek bude obsahovat zmiňované sloupce, ale první bude roztažen přes 3 a bude obsahovat konkrétní nápis buď Devizy nebo Valuty.&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;Style x:Key=&amp;quot;datagridHeaderStyle&amp;quot; TargetType=&amp;quot;primitives:DataGridColumnHeader&amp;quot;&amp;gt;
    &amp;lt;Setter Property=&amp;quot;Template&amp;quot;&amp;gt;
        &amp;lt;Setter.Value&amp;gt;
            &amp;lt;ControlTemplate TargetType=&amp;quot;primitives:DataGridColumnHeader&amp;quot;&amp;gt;
                &amp;lt;Grid x:Name=&amp;quot;Root&amp;quot;&amp;gt;
                    &amp;lt;Grid.ColumnDefinitions&amp;gt;
                        &amp;lt;ColumnDefinition/&amp;gt;
                        &amp;lt;ColumnDefinition Width=&amp;quot;Auto&amp;quot;/&amp;gt;
                    &amp;lt;/Grid.ColumnDefinitions&amp;gt;
                    &amp;lt;VisualStateManager.VisualStateGroups&amp;gt;
                        &amp;lt;VisualStateGroup x:Name=&amp;quot;CommonStates&amp;quot;&amp;gt;
                            &amp;lt;VisualState x:Name=&amp;quot;Normal&amp;quot;/&amp;gt;
                            &amp;lt;VisualState x:Name=&amp;quot;MouseOver&amp;quot;&amp;gt;
                                &amp;lt;Storyboard&amp;gt;
                                    &amp;lt;ColorAnimation Duration=&amp;quot;0&amp;quot; 
                                            Storyboard.TargetName=&amp;quot;BackgroundRectangle&amp;quot; 
                                            Storyboard.TargetProperty=&amp;quot;(Fill).Color&amp;quot; To=&amp;quot;#FF448DCA&amp;quot;/&amp;gt;
                                    &amp;lt;ColorAnimation Duration=&amp;quot;0&amp;quot; 
                                            Storyboard.TargetName=&amp;quot;BackgroundGradient&amp;quot; 
                                            Storyboard.TargetProperty=&amp;quot;(Fill).(GradientStops)[3].Color&amp;quot; To=&amp;quot;#7FFFFFFF&amp;quot;/&amp;gt;
                                    &amp;lt;ColorAnimation Duration=&amp;quot;0&amp;quot; 
                                            Storyboard.TargetName=&amp;quot;BackgroundGradient&amp;quot; 
                                            Storyboard.TargetProperty=&amp;quot;(Fill).(GradientStops)[2].Color&amp;quot; To=&amp;quot;#CCFFFFFF&amp;quot;/&amp;gt;
                                    &amp;lt;ColorAnimation Duration=&amp;quot;0&amp;quot; 
                                            Storyboard.TargetName=&amp;quot;BackgroundGradient&amp;quot; 
                                            Storyboard.TargetProperty=&amp;quot;(Fill).(GradientStops)[1].Color&amp;quot; To=&amp;quot;#F2FFFFFF&amp;quot;/&amp;gt;
                                &amp;lt;/Storyboard&amp;gt;
                            &amp;lt;/VisualState&amp;gt;
                            &amp;lt;VisualState x:Name=&amp;quot;Pressed&amp;quot;&amp;gt;
                                &amp;lt;Storyboard&amp;gt;
                                    &amp;lt;ColorAnimation Duration=&amp;quot;0&amp;quot; 
                                            Storyboard.TargetName=&amp;quot;BackgroundRectangle&amp;quot; 
                                            Storyboard.TargetProperty=&amp;quot;(Fill).Color&amp;quot; To=&amp;quot;#FF448DCA&amp;quot;/&amp;gt;
                                    &amp;lt;ColorAnimation Duration=&amp;quot;0&amp;quot; 
                                            Storyboard.TargetName=&amp;quot;BackgroundGradient&amp;quot; 
                                            Storyboard.TargetProperty=&amp;quot;(Fill).(GradientStops)[0].Color&amp;quot; To=&amp;quot;#D8FFFFFF&amp;quot;/&amp;gt;
                                    &amp;lt;ColorAnimation Duration=&amp;quot;0&amp;quot; 
                                            Storyboard.TargetName=&amp;quot;BackgroundGradient&amp;quot; 
                                            Storyboard.TargetProperty=&amp;quot;(Fill).(GradientStops)[1].Color&amp;quot; To=&amp;quot;#C6FFFFFF&amp;quot;/&amp;gt;
                                    &amp;lt;ColorAnimation Duration=&amp;quot;0&amp;quot; 
                                            Storyboard.TargetName=&amp;quot;BackgroundGradient&amp;quot; 
                                            Storyboard.TargetProperty=&amp;quot;(Fill).(GradientStops)[2].Color&amp;quot; To=&amp;quot;#8CFFFFFF&amp;quot;/&amp;gt;
                                    &amp;lt;ColorAnimation Duration=&amp;quot;0&amp;quot; 
                                            Storyboard.TargetName=&amp;quot;BackgroundGradient&amp;quot; 
                                            Storyboard.TargetProperty=&amp;quot;(Fill).(GradientStops)[3].Color&amp;quot; To=&amp;quot;#3FFFFFFF&amp;quot;/&amp;gt;
                                &amp;lt;/Storyboard&amp;gt;
                            &amp;lt;/VisualState&amp;gt;
                        &amp;lt;/VisualStateGroup&amp;gt;
                        &amp;lt;VisualStateGroup x:Name=&amp;quot;SortStates&amp;quot;&amp;gt;
                            &amp;lt;VisualState x:Name=&amp;quot;Unsorted&amp;quot;/&amp;gt;
                            &amp;lt;VisualState x:Name=&amp;quot;SortAscending&amp;quot; /&amp;gt;
                            &amp;lt;VisualState x:Name=&amp;quot;SortDescending&amp;quot; /&amp;gt;
                        &amp;lt;/VisualStateGroup&amp;gt;
                    &amp;lt;/VisualStateManager.VisualStateGroups&amp;gt;
                    &amp;lt;Rectangle x:Name=&amp;quot;BackgroundRectangle&amp;quot; Fill=&amp;quot;#FF1F3B53&amp;quot; Stretch=&amp;quot;Fill&amp;quot; Grid.ColumnSpan=&amp;quot;2&amp;quot;/&amp;gt;
                    &amp;lt;Rectangle x:Name=&amp;quot;BackgroundGradient&amp;quot; Stretch=&amp;quot;Fill&amp;quot; Grid.ColumnSpan=&amp;quot;2&amp;quot;&amp;gt;
                        &amp;lt;Rectangle.Fill&amp;gt;
                            &amp;lt;LinearGradientBrush EndPoint=&amp;quot;.7,1&amp;quot; StartPoint=&amp;quot;.7,0&amp;quot;&amp;gt;
                                &amp;lt;GradientStop Color=&amp;quot;#FCFFFFFF&amp;quot; Offset=&amp;quot;0.015&amp;quot;/&amp;gt;
                                &amp;lt;GradientStop Color=&amp;quot;#F7FFFFFF&amp;quot; Offset=&amp;quot;0.375&amp;quot;/&amp;gt;
                                &amp;lt;GradientStop Color=&amp;quot;#E5FFFFFF&amp;quot; Offset=&amp;quot;0.6&amp;quot;/&amp;gt;
                                &amp;lt;GradientStop Color=&amp;quot;#D1FFFFFF&amp;quot; Offset=&amp;quot;1&amp;quot;/&amp;gt;
                            &amp;lt;/LinearGradientBrush&amp;gt;
                        &amp;lt;/Rectangle.Fill&amp;gt;
                    &amp;lt;/Rectangle&amp;gt;
                    &amp;lt;Grid HorizontalAlignment=&amp;quot;{TemplateBinding HorizontalContentAlignment}&amp;quot;
                            VerticalAlignment=&amp;quot;{TemplateBinding VerticalContentAlignment}&amp;quot;&amp;gt;
                    &amp;lt;Grid.RowDefinitions&amp;gt;
                        &amp;lt;RowDefinition Height=&amp;quot;20&amp;quot;/&amp;gt;
                        &amp;lt;RowDefinition Height=&amp;quot;1&amp;quot;/&amp;gt;
                        &amp;lt;RowDefinition Height=&amp;quot;20&amp;quot;/&amp;gt;
                    &amp;lt;/Grid.RowDefinitions&amp;gt;
                    &amp;lt;Grid.ColumnDefinitions&amp;gt;
                        &amp;lt;ColumnDefinition Width=&amp;quot;50&amp;quot;/&amp;gt;
                        &amp;lt;ColumnDefinition Width=&amp;quot;1&amp;quot;/&amp;gt;
                        &amp;lt;ColumnDefinition Width=&amp;quot;50&amp;quot;/&amp;gt;
                        &amp;lt;ColumnDefinition Width=&amp;quot;1&amp;quot;/&amp;gt;
                        &amp;lt;ColumnDefinition Width=&amp;quot;50&amp;quot;/&amp;gt;
                    &amp;lt;/Grid.ColumnDefinitions&amp;gt;
                    &amp;lt;!-- Row 0 --&amp;gt;
                    &amp;lt;ContentPresenter Content=&amp;quot;{TemplateBinding Content}&amp;quot;
                                        VerticalAlignment=&amp;quot;Center&amp;quot;
                                        HorizontalAlignment=&amp;quot;Center&amp;quot;
                                        Grid.ColumnSpan=&amp;quot;5&amp;quot;/&amp;gt;
                    &amp;lt;!-- Row 1 --&amp;gt;
                    &amp;lt;Rectangle Fill=&amp;quot;#FFC9CACA&amp;quot; VerticalAlignment=&amp;quot;Stretch&amp;quot; Height=&amp;quot;1&amp;quot; 
                                Visibility=&amp;quot;Visible&amp;quot; Grid.Row=&amp;quot;1&amp;quot; Grid.ColumnSpan=&amp;quot;5&amp;quot; /&amp;gt;
                    &amp;lt;!-- Row 2 --&amp;gt;
                    &amp;lt;TextBlock Text=&amp;quot;Purchase&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;
                                HorizontalAlignment=&amp;quot;Center&amp;quot; Grid.Row=&amp;quot;2&amp;quot;/&amp;gt;
                    &amp;lt;Rectangle Fill=&amp;quot;#FFC9CACA&amp;quot; VerticalAlignment=&amp;quot;Stretch&amp;quot; Width=&amp;quot;1&amp;quot; 
                                Visibility=&amp;quot;Visible&amp;quot; Grid.Row=&amp;quot;2&amp;quot; Grid.Column=&amp;quot;1&amp;quot;/&amp;gt;
                    &amp;lt;TextBlock Text=&amp;quot;Sales&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;
                                HorizontalAlignment=&amp;quot;Center&amp;quot; Grid.Row=&amp;quot;2&amp;quot; Grid.Column=&amp;quot;2&amp;quot;/&amp;gt;
                    &amp;lt;Rectangle Fill=&amp;quot;#FFC9CACA&amp;quot; VerticalAlignment=&amp;quot;Stretch&amp;quot; Width=&amp;quot;1&amp;quot; 
                                Visibility=&amp;quot;Visible&amp;quot; Grid.Row=&amp;quot;2&amp;quot; Grid.Column=&amp;quot;3&amp;quot;/&amp;gt;
                    &amp;lt;TextBlock Text=&amp;quot;MidPoint&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;
                                HorizontalAlignment=&amp;quot;Center&amp;quot; Grid.Row=&amp;quot;2&amp;quot; Grid.Column=&amp;quot;4&amp;quot;/&amp;gt;
                &amp;lt;/Grid&amp;gt;
                &amp;lt;Rectangle x:Name=&amp;quot;VerticalSeparator&amp;quot; Fill=&amp;quot;#FFC9CACA&amp;quot; 
                            VerticalAlignment=&amp;quot;Stretch&amp;quot; Width=&amp;quot;1&amp;quot; Visibility=&amp;quot;Visible&amp;quot; 
                            Grid.Row=&amp;quot;1&amp;quot; Grid.Column=&amp;quot;1&amp;quot;/&amp;gt;
                &amp;lt;/Grid&amp;gt;
            &amp;lt;/ControlTemplate&amp;gt;
        &amp;lt;/Setter.Value&amp;gt;
    &amp;lt;/Setter&amp;gt;
&amp;lt;/Style&amp;gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Poznámka: Informace o tom jak upravit hlavičku datagridu jsem čerpal z následující &lt;/em&gt;&lt;a href="http://weblogs.asp.net/dwahlin/archive/2009/06/11/customizing-silverlight-3-datagrid-headers.aspx" target="_blank"&gt;&lt;em&gt;stránky&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ve stručnosti vysvětleno, jde o vytvoření gridu se 3 řádky a 5 sloupci. Kde v prvním řádku je hlavička (devizy nebo valuty), ve druhém oddělovač a v posledním hodnoty Prodej, oddělovač, nákup, oddělovač a střed (proto 5 sloupců). Upravíme tedy datagrid aby negenoravl sloupečky automaticky, ale nechal to na našem manuálním vytvoření&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;data:DataGrid Grid.Row=&amp;quot;1&amp;quot; ItemsSource=&amp;quot;{Binding Data}&amp;quot; 
                AutoGenerateColumns=&amp;quot;False&amp;quot; IsReadOnly=&amp;quot;True&amp;quot;&amp;gt;
    &amp;lt;data:DataGrid.Columns&amp;gt;
        &amp;lt;data:DataGridTextColumn Header=&amp;quot;Currency&amp;quot; 
                                    Binding=&amp;quot;{Binding Currency}&amp;quot;/&amp;gt;
        &amp;lt;data:DataGridTextColumn Header=&amp;quot;Country&amp;quot; 
                                    Binding=&amp;quot;{Binding Country}&amp;quot;/&amp;gt;
        &amp;lt;data:DataGridTextColumn Header=&amp;quot;Amount&amp;quot; 
                                    Binding=&amp;quot;{Binding Amount}&amp;quot;/&amp;gt;
        &amp;lt;data:DataGridTextColumn Header=&amp;quot;Change&amp;quot; 
                                    Binding=&amp;quot;{Binding Change, StringFormat=P}&amp;quot;/&amp;gt;
        &amp;lt;data:DataGridTemplateColumn Header=&amp;quot;Cashless&amp;quot; HeaderStyle=&amp;quot;{StaticResource datagridHeaderStyle}&amp;quot;&amp;gt;
            &amp;lt;data:DataGridTemplateColumn.CellTemplate&amp;gt;
                &amp;lt;DataTemplate&amp;gt;
                    &amp;lt;StackPanel Orientation=&amp;quot;Horizontal&amp;quot;&amp;gt;
                        &amp;lt;TextBlock Text=&amp;quot;{Binding PurchaseCashless}&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;
                                HorizontalAlignment=&amp;quot;Center&amp;quot; Width=&amp;quot;50&amp;quot;/&amp;gt;
                        &amp;lt;Rectangle Fill=&amp;quot;#FFC9CACA&amp;quot; VerticalAlignment=&amp;quot;Stretch&amp;quot; Width=&amp;quot;1&amp;quot; 
                                Visibility=&amp;quot;Visible&amp;quot;/&amp;gt;
                        &amp;lt;TextBlock Text=&amp;quot;{Binding SalesCashless}&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;
                                HorizontalAlignment=&amp;quot;Center&amp;quot; Width=&amp;quot;50&amp;quot;/&amp;gt;
                        &amp;lt;Rectangle Fill=&amp;quot;#FFC9CACA&amp;quot; VerticalAlignment=&amp;quot;Stretch&amp;quot; Width=&amp;quot;1&amp;quot; 
                                Visibility=&amp;quot;Visible&amp;quot;/&amp;gt;
                        &amp;lt;TextBlock Text=&amp;quot;{Binding MidPointCashless}&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;
                                HorizontalAlignment=&amp;quot;Center&amp;quot; Width=&amp;quot;50&amp;quot;/&amp;gt;
                    &amp;lt;/StackPanel&amp;gt;
                &amp;lt;/DataTemplate&amp;gt;
            &amp;lt;/data:DataGridTemplateColumn.CellTemplate&amp;gt;
        &amp;lt;/data:DataGridTemplateColumn&amp;gt;
        &amp;lt;data:DataGridTemplateColumn Header=&amp;quot;Cash&amp;quot; HeaderStyle=&amp;quot;{StaticResource datagridHeaderStyle}&amp;quot;&amp;gt;
            &amp;lt;data:DataGridTemplateColumn.CellTemplate&amp;gt;
                &amp;lt;DataTemplate&amp;gt;
                    &amp;lt;StackPanel Orientation=&amp;quot;Horizontal&amp;quot;&amp;gt;
                        &amp;lt;TextBlock Text=&amp;quot;{Binding PurchaseCash}&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;
                                HorizontalAlignment=&amp;quot;Center&amp;quot; Width=&amp;quot;50&amp;quot;/&amp;gt;
                        &amp;lt;Rectangle Fill=&amp;quot;#FFC9CACA&amp;quot; VerticalAlignment=&amp;quot;Stretch&amp;quot; Width=&amp;quot;1&amp;quot; 
                                Visibility=&amp;quot;Visible&amp;quot;/&amp;gt;
                        &amp;lt;TextBlock Text=&amp;quot;{Binding SalesCash}&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;
                                HorizontalAlignment=&amp;quot;Center&amp;quot; Width=&amp;quot;50&amp;quot;/&amp;gt;
                        &amp;lt;Rectangle Fill=&amp;quot;#FFC9CACA&amp;quot; VerticalAlignment=&amp;quot;Stretch&amp;quot; Width=&amp;quot;1&amp;quot; 
                                Visibility=&amp;quot;Visible&amp;quot;/&amp;gt;
                        &amp;lt;TextBlock Text=&amp;quot;{Binding MidPointCash}&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;
                                HorizontalAlignment=&amp;quot;Center&amp;quot; Width=&amp;quot;50&amp;quot;/&amp;gt;
                    &amp;lt;/StackPanel&amp;gt;
                &amp;lt;/DataTemplate&amp;gt;
            &amp;lt;/data:DataGridTemplateColumn.CellTemplate&amp;gt;
        &amp;lt;/data:DataGridTemplateColumn&amp;gt;
        &amp;lt;data:DataGridTextColumn Header=&amp;quot;Chart&amp;quot; 
                                 Binding=&amp;quot;{Binding Chart}&amp;quot;
			      Width=&amp;quot;*&amp;quot;/&amp;gt;
    &amp;lt;/data:DataGrid.Columns&amp;gt;
&amp;lt;/data:DataGrid&amp;gt;&lt;/pre&gt;

&lt;p&gt;Většina sloupečků je typu TextColumn, protože nám stačí zobrazení pouhého textu, ale u hodnot pro Devizy a Valuty je nutné použít TemplateColumn. Pomocí DataTemplate vytvoříme StackPanel, obsahující 3x Textbox (Nákup, Prodej, Střed) oddělený oddělovačem (podobně jako v definici stylu)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_10.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_10.png" width="244" height="169" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Poznámka: U posledního sloupce Chart nastavíme šířku pomocí hvězdičky, což znamená, že se sloupec roztáhne až do konce celého datagridu.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. krok – Přidání odkazu&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aby naše aplikace byla dle našich představ je potřeba přidat odkaz u sloupce Country, tzn. když uživatel klikne na název země, aby došlo k přesměrování na stránky s detailními infromacemi o měně. Pro tuto funkcionalitu si vytvoříme vlastní DetailLinkButton. Je potřeba nastavit NavigateUri na odkaz dle aktuální měny, která se předává jako parametr.&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class DetailLinkButton : HyperlinkButton
{
    private const string BaseCsUri = &amp;quot;http://www.csob.cz/cz/Csob/Kurzovni-listky/Stranky/kurzovni-listek-detail.aspx?Currency=AUD={0}&amp;quot;;

    public static readonly DependencyProperty CurrencyProperty =
        DependencyProperty.Register(&amp;quot;Currency&amp;quot;, typeof(string),
        typeof(DetailLinkButton), null);

    public DetailLinkButton()
    {
        Click += DetailLinkOnClick;
    }

    void DetailLinkOnClick(object sender, RoutedEventArgs e)
    {
        TargetName = &amp;quot;_blank&amp;quot;;
        NavigateUri = new Uri(string.Format(BaseCsUri, Currency));
    }

    public string Currency
    {
        get { return GetValue(CurrencyProperty).ToString(); }
        set { SetValue(CurrencyProperty, value); }
    }
}&lt;/pre&gt;

&lt;p&gt;Stačí už jenom upraviz xaml, aby místo DataGridTextColumn používal DetailLinkButton&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;data:DataGridTemplateColumn Header=&amp;quot;Country&amp;quot;&amp;gt;
    &amp;lt;data:DataGridTemplateColumn.CellTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;local:DetailLinkButton Currency=&amp;quot;{Binding Currency}&amp;quot;
                                    Content=&amp;quot;{Binding Country}&amp;quot;/&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/data:DataGridTemplateColumn.CellTemplate&amp;gt;
&amp;lt;/data:DataGridTemplateColumn&amp;gt;&lt;/pre&gt;

&lt;p&gt;Do Currency si načteme kód měny a jako obsah odkazu zůstane název země. Podobně se změní i sloupec pro graf, kde nyní použijeme ikonu&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;data:DataGridTemplateColumn Header=&amp;quot;Chart&amp;quot; Width=&amp;quot;*&amp;quot;&amp;gt;
    &amp;lt;data:DataGridTemplateColumn.CellTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;local:DetailLinkButton Currency=&amp;quot;{Binding Currency}&amp;quot;&amp;gt;
                &amp;lt;Image Source=&amp;quot;Images/ico-graf.png&amp;quot; Stretch=&amp;quot;Fill&amp;quot; Width=&amp;quot;16&amp;quot; Height=&amp;quot;16&amp;quot;/&amp;gt;
            &amp;lt;/local:DetailLinkButton&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/data:DataGridTemplateColumn.CellTemplate&amp;gt;
&amp;lt;/data:DataGridTemplateColumn&amp;gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;7. krok – Přidání ikon&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Jeden obrázek už v aplikaci máme a nyní přidáme ostatní. Nejdříve přidáme jednotlivé vlaječky k názvům měny. Tyto vlaječky si uložíme do složky Images&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_11.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_11.png" width="128" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A k tomu aby jsme je zobrazily v gridu, bude potřeba vytvořit Converter, který na základě kódu měny vrátí správný název obrázku.&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class CurrencyToImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if ( value == null )
            return null;

        return string.Format(&amp;quot;Images/{0}.png&amp;quot;, value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}&lt;/pre&gt;

&lt;p&gt;V xamlu pak stačí upravit pár řádků pro Currency&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;data:DataGridTemplateColumn Header=&amp;quot;Currency&amp;quot;&amp;gt;
    &amp;lt;data:DataGridTemplateColumn.CellTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;StackPanel Orientation=&amp;quot;Horizontal&amp;quot;&amp;gt;
                &amp;lt;Image Source=&amp;quot;{Binding Currency, Converter={StaticResource conv}}&amp;quot;
                        Width=&amp;quot;16&amp;quot; Height=&amp;quot;16&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;
                        HorizontalAlignment=&amp;quot;Center&amp;quot; Margin=&amp;quot;5&amp;quot;/&amp;gt;
                &amp;lt;TextBlock Text=&amp;quot;{Binding Currency}&amp;quot;
                            VerticalAlignment=&amp;quot;Center&amp;quot;
                            HorizontalAlignment=&amp;quot;Center&amp;quot;
                            Margin=&amp;quot;5&amp;quot;/&amp;gt;
            &amp;lt;/StackPanel&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/data:DataGridTemplateColumn.CellTemplate&amp;gt;
&amp;lt;/data:DataGridTemplateColumn&amp;gt;&lt;/pre&gt;

&lt;p&gt;a Chart&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;data:DataGridTemplateColumn Header=&amp;quot;Chart&amp;quot; Width=&amp;quot;*&amp;quot;&amp;gt;
    &amp;lt;data:DataGridTemplateColumn.CellTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;local:DetailLinkButton Currency=&amp;quot;{Binding Currency}&amp;quot; Margin=&amp;quot;5&amp;quot;&amp;gt;
                &amp;lt;Image Source=&amp;quot;Images/ico-graf.png&amp;quot; Stretch=&amp;quot;Fill&amp;quot; Width=&amp;quot;16&amp;quot; Height=&amp;quot;16&amp;quot;/&amp;gt;
            &amp;lt;/local:DetailLinkButton&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/data:DataGridTemplateColumn.CellTemplate&amp;gt;
&amp;lt;/data:DataGridTemplateColumn&amp;gt;&lt;/pre&gt;

&lt;p&gt;V poslední řadě si pak vytvoříme konverte, který na základě změny (Change) zobrazí buď zelenou (kladné hodnoty), modrou (beze změny), červenou šipku (záporné hodnoty)&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class ChangeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if ( value == null )
            return null;

        float change = float.Parse(value.ToString());
        if ( change &amp;gt; 0 )
            return &amp;quot;Images/arrow_up_green.png&amp;quot;;
        else if ( change == 0 )
            return &amp;quot;Images/arrow_right_blue.png&amp;quot;;
        else
            return &amp;quot;Images/arrow_down_red.png&amp;quot;;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}&lt;/pre&gt;

&lt;p&gt;V xamlu bude úprava téměř totožná jako sloupeček s vlajkami.&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;data:DataGridTemplateColumn Header=&amp;quot;Change&amp;quot;&amp;gt;
    &amp;lt;data:DataGridTemplateColumn.CellTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;StackPanel Orientation=&amp;quot;Horizontal&amp;quot;&amp;gt;
                &amp;lt;TextBlock Text=&amp;quot;{Binding Change, StringFormat=P}&amp;quot;
                            VerticalAlignment=&amp;quot;Center&amp;quot; HorizontalAlignment=&amp;quot;Center&amp;quot;
                            Margin=&amp;quot;5&amp;quot;/&amp;gt;
                &amp;lt;Image Source=&amp;quot;{Binding Change, Converter={StaticResource conv2}}&amp;quot;
                        Width=&amp;quot;16&amp;quot; Height=&amp;quot;16&amp;quot; HorizontalAlignment=&amp;quot;Center&amp;quot;
                        VerticalAlignment=&amp;quot;Center&amp;quot; Margin=&amp;quot;5&amp;quot;/&amp;gt;
            &amp;lt;/StackPanel&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/data:DataGridTemplateColumn.CellTemplate&amp;gt;
&amp;lt;/data:DataGridTemplateColumn&amp;gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_12.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_12.png" width="244" height="172" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. krok – Lokalizace&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Předposledním krokem bude lokalizace aplikace, která ať se Vám může zdát složitá je naopak velice jednoduchá. Přidáme si do aplikace Resources (Strings.resx)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_13.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_13.png" width="244" height="196" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A anglickou verzi Strings.en-US.resx&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_14.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_14.png" width="244" height="168" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aby jsme se dostali ze XAMLu na naše Resources, přidíme si instanci jako StaticResource&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;local:CustomResources x:Key=&amp;quot;LocStrings&amp;quot;/&amp;gt;&lt;/pre&gt;

&lt;p&gt;LocStrings je typu CustomResources. Jedná se o pomocnou třídu, která má vlastnost LocalizedStrings typu Strings(Resource) a slouží především proto, že když uživatel za běhu změní kulturu, tak abych mohl notifikovat UI o tom, že došlo ke změně a došlo k přečtení správného resource&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class CustomResources : INotifyPropertyChanged
{
    private readonly Resources.Strings _strings = new Resources.Strings();

    public Resources.Strings LocalizedStrings
    {
        get { return _strings; }
        set { OnPropertyChanged(MethodBase.GetCurrentMethod()); }
    }

    public event PropertyChangedEventHandler  PropertyChanged;

    private void OnPropertyChanged(MethodBase methodBase)
    {
        if ( PropertyChanged != null )
        {
            PropertyChanged(this, new PropertyChangedEventArgs(methodBase.Name.Substring(4)));
        }
    }
}&lt;/pre&gt;

&lt;p&gt;Nyní všechen text, který mám v XAMLu natvrdo nahradím části kódu, která načte příslušný string na základě zvolené kultury. Ukázka jak toho docílit např. pro měnu:&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt; &amp;lt;TextBlock Text=&amp;quot;{Binding Source={StaticResource LocStrings}, Path=LocalizedStrings.Currency}&amp;quot;/&amp;gt;&lt;/pre&gt;

&lt;p&gt;Problém je, že toto nefunguje u vlastnosti Header, takže místo přeloženého textu se nám zobrazí System.Windows.Data.Binding. Je nutné to trošku objeít např. tímto způsobem&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class ExDataGridTextColumn : DataGridTextColumn
{
    public string ColumnHeader
    {
        get
        {
            return ( string ) GetValue(ColumnHeaderProperty);
        }
        set
        {
            SetValue(ColumnHeaderProperty, value);
        }
    }

    public static readonly DependencyProperty ColumnHeaderProperty =
        DependencyProperty.Register(&amp;quot;ColumnHeader&amp;quot;, typeof(string),
        typeof(ExDataGridTextColumn), new PropertyMetadata(ColumnHeaderChanged)
    );

    private static void ColumnHeaderChanged(object sender, DependencyPropertyChangedEventArgs args)
    {
        DataGridTextColumn dgc = sender as DataGridTextColumn;

        string h = (string) args.NewValue;
        if ( args.NewValue != args.OldValue )
        {
            dgc.Header = h;
        }
    }
}

public class ExDataGridTemplateColumn : DataGridTemplateColumn
{
    public string ColumnHeader
    {
        get
        {
            return ( string ) GetValue(ColumnHeaderProperty);
        }
        set
        {
            SetValue(ColumnHeaderProperty, value);
        }
    }

    public static readonly DependencyProperty ColumnHeaderProperty =
        DependencyProperty.Register(&amp;quot;ColumnHeader&amp;quot;, typeof(string),
        typeof(ExDataGridTemplateColumn), new PropertyMetadata(ColumnHeaderChanged)
    );

    private static void ColumnHeaderChanged(object sender, DependencyPropertyChangedEventArgs args)
    {
        ExDataGridTemplateColumn dgc = sender as ExDataGridTemplateColumn;

        string h = ( string ) args.NewValue;
        if ( args.NewValue != args.OldValue )
        {
            dgc.Header = h;
        }
    }
}&lt;/pre&gt;

&lt;p&gt;Vytvoříme si dvě třídy ExDataGridTextColumn a ExDataGridTemplateColumn, kde definujeme jednu vlastnost ColumnHeader. Tato vlastnost slouží jako náhrada vlastnosti Header (nyní lze už použít Binding). Můžeme tedy nastavit hlavičku sloupce jednoduchým způsobem:&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;ColumnHeader=&amp;quot;{Binding Source={StaticResource LocStrings}, Path=LocalizedStrings.Cash}&amp;quot;&lt;/pre&gt;

&lt;p&gt;Na závěr už pak jenom přidáme ComboBox, ve kterém bude seznam dostupných lokalizací a uživatel si tak bude moct zvolit, kterou jazykovou verzi bude chtít využít.&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;ComboBox x:Name=&amp;quot;ui_cbLanguages&amp;quot; SelectionChanged=&amp;quot;LanguagesOnSelectionChanged&amp;quot;
            HorizontalAlignment=&amp;quot;Right&amp;quot; Grid.Row=&amp;quot;0&amp;quot;&amp;gt;
    &amp;lt;ComboBoxItem Tag=&amp;quot;en-Us&amp;quot;&amp;gt;
        &amp;lt;Image Source=&amp;quot;Images/USD.png&amp;quot; Width=&amp;quot;16&amp;quot; Height=&amp;quot;16&amp;quot;/&amp;gt;
    &amp;lt;/ComboBoxItem&amp;gt;
    &amp;lt;ComboBoxItem Tag=&amp;quot;cs-CZ&amp;quot;&amp;gt;
        &amp;lt;Image Source=&amp;quot;Images/CZE.png&amp;quot; Width=&amp;quot;16&amp;quot; Height=&amp;quot;16&amp;quot;/&amp;gt;
    &amp;lt;/ComboBoxItem&amp;gt;
&amp;lt;/ComboBox&amp;gt;&lt;/pre&gt;

&lt;p&gt;No a v obsluze metody LanguagesOnSelectionChanged provedeme pouze změnu nastavení kultury&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;private void LanguagesOnSelectionChanged(object sender, SelectionChangedEventArgs args)
{
    ComboBoxItem item = ui_cbLanguages.SelectedItem as ComboBoxItem;
    string code = item.Tag.ToString();
    System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(code);
    System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(code);
    // notifikuju o zmene
    (( CustomResources ) this.Resources[&amp;quot;LocStrings&amp;quot;]).LocalizedStrings = new Resources.Strings();
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;9. krok – Izolované uložiště&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Úplně poslední krok dnešního tutoriálu je ukázka jak využít izolované uložiště. Jakmile se aplikace spustí, stáhne data pomocí WCF služby a poté uloží stažené data do izolovaného uložiště. Při dalším spuštění aplikace ověří, zda již neexistují data a pokud existují a jsou platná, nahrají se z toho uložiště a není potřeba volat znovu WCF službu.&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;private void SaveData(string data, string path)
{
    using ( IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication() )
    {
        using ( IsolatedStorageFileStream isolatedStorageFileStream = 
            new IsolatedStorageFileStream(path, FileMode.Create, file) )
        {
            using ( StreamWriter writer = new StreamWriter(isolatedStorageFileStream) )
            {
                writer.Write(data);
            }
        }
    }
}

public bool GetData(string path, out string data)
{
    data = string.Empty;

    using ( IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication() )
    {
        if ( !file.FileExists(path) )
            return false;

        using ( IsolatedStorageFileStream isolatedStorageFileStream = 
            new IsolatedStorageFileStream(path, FileMode.OpenOrCreate, file) )
        {
            using ( StreamReader reader = new StreamReader(isolatedStorageFileStream) )
            {
                string dateTimeLine = reader.ReadLine();
                DateTime lastDateTime = DateTime.Parse(dateTimeLine);
                if ( lastDateTime.Year != DateTime.Now.Year ||
                        lastDateTime.DayOfYear != DateTime.Now.DayOfYear )
                    return false;

                reader.BaseStream.Position = 0;
                data = reader.ReadToEnd();
            }
        }
    }
    return true;
}&lt;/pre&gt;

&lt;p&gt;
  

  

  

  &lt;p&gt;A kontrola v Load události&lt;/p&gt;

  &lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;void MainPageOnLoaded(object sender, RoutedEventArgs args)
{
    // podivam se do izolovaneho uloziste
    string data =string.Empty;
    if ( !GetData(&amp;quot;kurzy.txt&amp;quot;, out data) )
    {
        var proxy = new ExchangeRatesServiceClient();
        proxy.GetDataCompleted += GetDataOnCompleted;
        proxy.GetDataAsync();
    }
    else
    {
        FillData(data);
    }
}&lt;/pre&gt;

  &lt;p&gt;Tááák a to je pro tuto ukázku vše. Pokud jse se dočetli až sem, tak jsem rád, protože já sám měl problém to do takových rozměrů sepsat &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lukaskubis.net/image.axd?picture=wlEmoticon-smile_1.png" /&gt;&lt;/p&gt;

  &lt;p&gt;Ukázkovou aplikaci lze stáhnout na adrese &lt;a href="http://lukaskubis.net/Demos/ExchangeRatesSample.zip"&gt;http://lukaskubis.net/Demos/ExchangeRatesSample.zip&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;</description>
      <link>http://lukaskubis.net/post/Silverlight-4-Kurzovni-listek-e28093-krok-za-krokem.aspx</link>
      <author>lukask</author>
      <comments>http://lukaskubis.net/post/Silverlight-4-Kurzovni-listek-e28093-krok-za-krokem.aspx#comment</comments>
      <guid>http://lukaskubis.net/post.aspx?id=95569ad4-5e3c-48d1-8edf-4e818c76d05c</guid>
      <pubDate>Mon, 27 Dec 2010 09:49:42 +1000</pubDate>
      <dc:publisher>lukask</dc:publisher>
      <pingback:server>http://lukaskubis.net/pingback.axd</pingback:server>
      <pingback:target>http://lukaskubis.net/post.aspx?id=95569ad4-5e3c-48d1-8edf-4e818c76d05c</pingback:target>
      <slash:comments>5</slash:comments>
      <trackback:ping>http://lukaskubis.net/trackback.axd?id=95569ad4-5e3c-48d1-8edf-4e818c76d05c</trackback:ping>
      <wfw:comment>http://lukaskubis.net/post/Silverlight-4-Kurzovni-listek-e28093-krok-za-krokem.aspx#comment</wfw:comment>
      <wfw:commentRss>http://lukaskubis.net/syndication.axd?post=95569ad4-5e3c-48d1-8edf-4e818c76d05c</wfw:commentRss>
    </item>
    <item>
      <title>Windows Phone 7 - začínáme</title>
      <description>&lt;p&gt;Dneska jsem se rozhodl, že se podívám trošku pod pokličku Windows Phone 7 (dále jen WP7) a tak tady budu sepisovat jednotlivé články na různá témata. Nejdříve zde přidám pár zajímavých odkazů, které je dobré znát&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2010/09/16/windows-phone-7-developer-tools-released.aspx" target="_blank"&gt;ScottGu’s Blog&lt;/a&gt; – oznámení o release verze WP7 Developer Tools (obsahuje základní informace + odkazy na další zajimavé stránky věnující se tomuto tématu) &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/wp7trainingcourse.aspx" target="_blank"&gt;MSDN&lt;/a&gt; – WP7 Training Course (výukový kurz) – lze stáhnout i v offline verzi &lt;/li&gt;    &lt;li&gt;&lt;a href="http://channel9.msdn.com/Series/Windows-Phone-7-Development-for-Absolute-Beginners" target="_blank"&gt;Channel 9&lt;/a&gt; – Kurz pro absolutní začátečníky &lt;/li&gt;    &lt;li&gt;&lt;a href="http://click.email.microsoftemail.com/?qs=c20735197848074e67c05059467a85ac0bcb63706acc4cc103ceea9903994b3eab37ceca9da8dbd2" target="_blank"&gt;E-book&lt;/a&gt; – Elektronická kniha o Programování WP 7 zdarma od Charlesa Petzolda &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Než se pustím do psaní o WP7, rád bych zde udržoval seznam již publikovaných článků:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://lukaskubis.net/post/Windows-Phone-7-zaciname.aspx" target="_blank"&gt;WP7 – začínáme&lt;/a&gt;       &lt;ul&gt;       &lt;li&gt;Seznámení s WP7 + vytvoření HelloWorld aplikace &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;a href="http://lukaskubis.net/post/Windows-Phone-7e28093jak-na-orientaci.aspx" target="_blank"&gt;WP7 – jak na orientaci&lt;/a&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Podporované orientace, reakce na změnu orientace&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;WP7 - &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Na WP7 již bylo napsáno několik recenzí, tak se pojďme podívat jenom v krátkosti, jak vůbec vypadá, co obsahuje apod.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://t2.gstatic.com/images?q=tbn:auuWeR3sZaGF3M:http://cdn.thetechjournal.com/wp-content/uploads/windows-phone-7-first-look-15.jpg&amp;amp;t=1" width="305" height="306" /&gt;&lt;/p&gt;  &lt;h2&gt;Tlačítka&lt;/h2&gt;  &lt;p&gt;Jak můžeme vidět úplně dole se nachází pouze tři tlačítka&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Zpět&lt;/strong&gt; – toto tlačítka má podobnou funkcionalitu jako např. tlačítko zpět v prohlížeči, tedy návrat na předchozí stránku. Pokud se ovšem nacházíme na úvodní stránce aplikace, tak po stisku tohoto tlačítka dojde k ukončení aplikace &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Start&lt;/strong&gt; – zobrazí uživateli nabídku start &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Hledat&lt;/strong&gt; – slouží pro hledání &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Displej&lt;/h2&gt;  &lt;p&gt;V první verzi je k dispozici displej o rozměrech 480 x 800 pixelů. V budoucí verzi je naplánovaná podpora i pro rozlišení 320 x 480 pixelů.&lt;/p&gt;  &lt;h2&gt;&lt;strong&gt;Multi-touch&lt;/strong&gt;&lt;/h2&gt;  &lt;p&gt;Displej je schopný rozpoznat ovládání lidským prstem, ale nezvládne už ovládání pomocí stylusu, či jiné “pomůcky”.&lt;/p&gt;  &lt;h2&gt;Sensory a služby&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;Wi-Fi &lt;/li&gt;    &lt;li&gt;GPS &lt;/li&gt;    &lt;li&gt;Fotoaparát &lt;/li&gt;    &lt;li&gt;FM rádio &lt;/li&gt;    &lt;li&gt;Akcelerometr – reaguje na pohyb telefonu &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;em&gt;Poznámka: Informace výše o telefonu pocházejí z různých zdrojů. Bohužel se mi ještě nepodařilo dostat telefon do svých rukou.&lt;/em&gt;&lt;/p&gt;  &lt;h2&gt;Vytváříme nový projekt&lt;/h2&gt;  &lt;p&gt;Pokud máme nainstalované Windows Phone 7 Developer Tools, tak při výběru nového projektu máme možnost, zda si vytvoříme aplikaci v silverlightu, nebo pomocí XNA.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Silverligh for Windows Phone&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_6.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Silverligh for Windows Phone" border="0" alt="Silverligh for Windows Phone" src="http://lukaskubis.net/image.axd?picture=image_thumb_6.png" width="244" height="137" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;XNA Game Studio 4.0&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_7.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="XNA Game Studio 4.0" border="0" alt="XNA Game Studio 4.0" src="http://lukaskubis.net/image.axd?picture=image_thumb_7.png" width="244" height="128" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;My se momentálně budeme zabývat pouze vývojem Silverlight aplikací. Vybereme tedy Silverlight Phone Application a pojmenujeme si jí jak jinak, než HelloWorld &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lukaskubis.net/image.axd?picture=wlEmoticon-smile.png" /&gt;. Po vytvoření projektu se vytvoří základní struktura s potřebnými soubory. Pojďme se na ní podívat:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;HelloWorld – název projektu      &lt;ul&gt;       &lt;li&gt;[Properties] – název složky          &lt;ul&gt;           &lt;li&gt;AppManifest.xml – momentálně &amp;quot;prázdný&amp;quot; &lt;/li&gt;            &lt;li&gt;AssemblyInfo.cs – informace o assembly &lt;/li&gt;            &lt;li&gt;WMAppManifest.xml – obsahuje následující informace              &lt;ul&gt;               &lt;li&gt;Název, autor, popis, vydavatel aplikace &lt;/li&gt;                &lt;li&gt;Název ikony &lt;/li&gt;                &lt;li&gt;Url adresa obrázku pro pozadí &lt;/li&gt;                &lt;li&gt;název úvodní stránky &lt;/li&gt;                &lt;li&gt;apod. &lt;/li&gt;             &lt;/ul&gt;           &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;App.xaml – definuje pouze události Lanching, Closing, Activated, Deactivated objektu PhoneApplicationService &lt;/li&gt;        &lt;li&gt;App.xaml.cs – obsluha událostí, inicializace komponent, odchycení neodchycených výjimek a další nutné operace pro spuštění aplikace &lt;/li&gt;        &lt;li&gt;MainPage.xaml – úvodní stránka s obsahem, která se zobrazí po spuštění aplikace &lt;/li&gt;        &lt;li&gt;MainPage.xaml.cs – Kód na pozadí (obsluha událostí, inicializace, apod.) &lt;/li&gt;        &lt;li&gt;ApplicationIcon.png – ikona aplikace &lt;/li&gt;        &lt;li&gt;Background.png – obrázek pozadí aplikace &lt;/li&gt;        &lt;li&gt;SplashScreenImage.jpg – obrázek, který se zobrazí během spouštění aplikace &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Než provedeme spuštění aplikace, musíme si ověřit, že máme nastavený WP7 Emulator. V případě, že by jsme měli nastavený WP7 Device, aplikace by se nahrála přímo do našeho zařízení. Pro testovací účely necháme vybranou možnost WP7 Emulator. První spuštění bude trvat kapánek déle a po nějaké chvíli se nám objeví emulátor WP7 se spuštěnou aplikací. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lukaskubis.net/image.axd?picture=image_8.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lukaskubis.net/image.axd?picture=image_thumb_8.png" width="132" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Jakmile aplikaci ukončíme, můžeme si všimnout, že emulátor zůstane spuštěný (pokud jsme ho nezavřeli pomocí křížku). Další následné spuštění už je o dost rychlejší.&lt;/p&gt;  &lt;p&gt;Upravíme tedy aplikaci, aby aspoň někde zobrazovala Hello World. Upravíme MainPage.xaml tak, že zde přidáme jedno tlačítko s popisem Klikni&lt;/p&gt;  &lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;StackPanel x:Name=&amp;quot;TitlePanel&amp;quot; Grid.Row=&amp;quot;0&amp;quot; Margin=&amp;quot;12,17,0,28&amp;quot;&amp;gt;
    &amp;lt;TextBlock x:Name=&amp;quot;ApplicationTitle&amp;quot; Text=&amp;quot;Hello World Sample&amp;quot; Style=&amp;quot;{StaticResource PhoneTextNormalStyle}&amp;quot;/&amp;gt;
    &amp;lt;TextBlock x:Name=&amp;quot;PageTitle&amp;quot; Text=&amp;quot;page name:&amp;quot; Margin=&amp;quot;9,-7,0,0&amp;quot; Style=&amp;quot;{StaticResource PhoneTextTitle1Style}&amp;quot;/&amp;gt;
    &amp;lt;Button Content=&amp;quot;Klikni&amp;quot; Click=&amp;quot;Button_Click&amp;quot;/&amp;gt;
&amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;

&lt;p&gt;Obsluha kliknutí na tlačítko&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;private void Button_Click(object sender, RoutedEventArgs e)
{
    PageTitle.Text = &amp;quot;Hello World!!!&amp;quot;;
}&lt;/pre&gt;

&lt;p&gt;Naše aplikace po stisknutí tlačítka klikni změní text z &amp;quot;page name&amp;quot; na &amp;quot;Hello World!!!&amp;quot;.&lt;/p&gt;

&lt;p&gt;To je pro dnešní díl vše a v brzké době se můžete těšit na pokračování, kde si už trošku více zaprogramujeme.&lt;/p&gt;</description>
      <link>http://lukaskubis.net/post/Windows-Phone-7-zaciname.aspx</link>
      <author>lukask</author>
      <comments>http://lukaskubis.net/post/Windows-Phone-7-zaciname.aspx#comment</comments>
      <guid>http://lukaskubis.net/post.aspx?id=5c8088aa-eacf-404f-9717-5e8d5559cfee</guid>
      <pubDate>Thu, 23 Dec 2010 07:47:55 +1000</pubDate>
      <dc:publisher>lukask</dc:publisher>
      <pingback:server>http://lukaskubis.net/pingback.axd</pingback:server>
      <pingback:target>http://lukaskubis.net/post.aspx?id=5c8088aa-eacf-404f-9717-5e8d5559cfee</pingback:target>
      <slash:comments>6</slash:comments>
      <trackback:ping>http://lukaskubis.net/trackback.axd?id=5c8088aa-eacf-404f-9717-5e8d5559cfee</trackback:ping>
      <wfw:comment>http://lukaskubis.net/post/Windows-Phone-7-zaciname.aspx#comment</wfw:comment>
      <wfw:commentRss>http://lukaskubis.net/syndication.axd?post=5c8088aa-eacf-404f-9717-5e8d5559cfee</wfw:commentRss>
    </item>
    <item>
      <title>Silverlight–vyvolání PropertyChanged události</title>
      <description>&lt;p&gt;Dnešní článek bude spíše takový sourn toho co jsem objevil na internetu.&lt;/p&gt;  &lt;p&gt;Všichni, kdo vytváříte silverlight aplikace. jste již setkali s rozhraním INotifyPropertyChanged. “Otrocké” vytváření vlastností tímto způsobm bylo na denním pořadku:&lt;/p&gt;  &lt;h2&gt;Textový název vlastnosti&lt;/h2&gt;  &lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public string FirstName
{
    get { return _firstName; }
    set
    {
        _firstName = value;
        RaisePropertyChanged(&amp;quot;FirstName&amp;quot;);
    }
}&lt;/pre&gt;

&lt;p&gt;Avšak tento způsob není ideální, protože zde zadáváme název vlastnosti jako string a většina z nás využívá techniku “copy/paste” takže zde může dojít jednoduše k chybám. Další způsob, jak vyvolat událost PropertyChanged už je trochu lepší a to využitím lambda výrazů, ze kterého pak odvodíme název vlastnosti…&lt;/p&gt;

&lt;h2&gt;Lambda výraz&lt;/h2&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public string FirstName
{
    get { return _firstName; }
    set
    {
        _firstName = value;
        RaisePropertyChanged(()=&amp;gt;FirstName);
    }
}&lt;/pre&gt;

&lt;p&gt;…ovšem i zde, si nemůžeme být jistí, že neuděláme chybu a omylem nevyužijeme jinou vlastnost, např. LastName. Co když ale upravíme vlastnost FirstName tak, aby vypadala následovně&lt;/p&gt;

&lt;h2&gt;StackTrace&lt;/h2&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public string FirstName
{
    get { return _firstName; }
    set
    {
        _firstName = value;
        RaisePropertyChanged();
    }
}&lt;/pre&gt;

&lt;p&gt;Voláme zde RaisePropertyChanged, ale bez parametru! Tělo metody RaisePropertyChanged vypadá takhle&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public virtual void RaisePropertyChanged()
{
    var frames = new System.Diagnostics.StackTrace();
    for (var i = 0; i &amp;lt; frames.FrameCount; i++)
    {
        var frame = frames.GetFrame(i).GetMethod() as MethodInfo;
        if (frame != null)
            if (frame.IsSpecialName &amp;amp;&amp;amp; frame.Name.StartsWith(&amp;quot;set_&amp;quot;))
            {
                RaisePropertyChanged(frame.Name.Substring(4));
                return;
            }
    }
    throw new InvalidOperationException(&amp;quot;NotifyPropertyChanged() can only by invoked within a property setter.&amp;quot;);
}&lt;/pre&gt;

&lt;p&gt;Pomocí vlastnosti StackTrace se dostanu na informaci, který setter sevolá (konvence pro setter je set_propertyName). Jednoduše se tedy zbavím prefixu set_ a zbytek použiju jako parametr při volání PropertyChanged události.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Informace výše jsem převzal z článku &lt;/em&gt;&lt;em&gt;&lt;a href="http://csharperimage.jeremylikness.com/2010/12/jounce-part-8-raising-property-changed.html"&gt;http://csharperimage.jeremylikness.com/2010/12/jounce-part-8-raising-property-changed.html&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;MethodBase.GetCurrentMethod()&lt;/h2&gt;

&lt;p&gt;Další způsob jak se vyhnout specifikování názvu vlastnosti je využít metody GetCurrentMethod, která vrátí název aktuálně prováděné operace. V případě setteru to bude set_FirstName.&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public string FirstName
{
    get { return _firstName; }
    set
    {
        _firstName = value;
        RaisePropertyChanged(System.Reflection.MethodBase.GetCurrentMethod());
    }
}&lt;/pre&gt;

&lt;p&gt;Využíváte ještě jiný způsob notifikace? Podělte se s ostatními pomocí komentářů pod článkem.
  &lt;/p&gt;</description>
      <link>http://lukaskubis.net/post/Silverlighte28093vyvolani-PropertyChanged-udalosti.aspx</link>
      <author>lukask</author>
      <comments>http://lukaskubis.net/post/Silverlighte28093vyvolani-PropertyChanged-udalosti.aspx#comment</comments>
      <guid>http://lukaskubis.net/post.aspx?id=063715d3-ff68-464f-9564-3df071612faf</guid>
      <pubDate>Sun, 19 Dec 2010 09:56:51 +1000</pubDate>
      <dc:publisher>lukask</dc:publisher>
      <pingback:server>http://lukaskubis.net/pingback.axd</pingback:server>
      <pingback:target>http://lukaskubis.net/post.aspx?id=063715d3-ff68-464f-9564-3df071612faf</pingback:target>
      <slash:comments>10</slash:comments>
      <trackback:ping>http://lukaskubis.net/trackback.axd?id=063715d3-ff68-464f-9564-3df071612faf</trackback:ping>
      <wfw:comment>http://lukaskubis.net/post/Silverlighte28093vyvolani-PropertyChanged-udalosti.aspx#comment</wfw:comment>
      <wfw:commentRss>http://lukaskubis.net/syndication.axd?post=063715d3-ff68-464f-9564-3df071612faf</wfw:commentRss>
    </item>
    <item>
      <title>Silverlight–WebClient II.–zobrazení RSS</title>
      <description>&lt;p&gt;V minulém &lt;a href="http://lukaskubis.net/post/Silverlighte28093WebClient-I-stahnuti-souboru.aspx" target="_blank"&gt;článku&lt;/a&gt; jsme si ukázali jak pomocí třídy WebClient stáhnout obsah souboru. Dnes si ukážeme možnost, jak v naší aplikaci zobrazit RSS kanál.&lt;/p&gt;  &lt;h2&gt;Design aplikace&lt;/h2&gt;  &lt;p&gt;Design aplikace je velice jednoduchý. Naše uživatelské rozhraní obsahuje pouze tlačítko, které po stisku zobrazí obsah jednoho RSS kanálu.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Pro testovací účely jsem si v mojí webové aplikaci vytvořil adresář Files, do kterého jsem umístil soubor posts.rss&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Obsah RSS kanálu se zobrazuje pomocí ItemsControl, kde jsem si vytvořil vlastní šablonu aby výsledek vypadal aspoň trošku k světu:&lt;/p&gt;  &lt;pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;&amp;lt;UserControl x:Class=&amp;quot;WebClientViewRssSample.MainPage&amp;quot;
    xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
    xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;
    xmlns:d=&amp;quot;http://schemas.microsoft.com/expression/blend/2008&amp;quot;
    xmlns:mc=&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot;
    mc:Ignorable=&amp;quot;d&amp;quot;
    d:DesignHeight=&amp;quot;300&amp;quot; d:DesignWidth=&amp;quot;400&amp;quot;&amp;gt;

    &amp;lt;Grid x:Name=&amp;quot;LayoutRoot&amp;quot; Background=&amp;quot;White&amp;quot;&amp;gt;
        &amp;lt;Grid.RowDefinitions&amp;gt;
            &amp;lt;RowDefinition Height=&amp;quot;40&amp;quot;/&amp;gt;
            &amp;lt;RowDefinition Height=&amp;quot;*&amp;quot;/&amp;gt;
        &amp;lt;/Grid.RowDefinitions&amp;gt;
        &amp;lt;Grid.ColumnDefinitions&amp;gt;
            &amp;lt;ColumnDefinition Width=&amp;quot;100&amp;quot;/&amp;gt;
            &amp;lt;ColumnDefinition Width=&amp;quot;*&amp;quot;/&amp;gt;
        &amp;lt;/Grid.ColumnDefinitions&amp;gt;
        &amp;lt;Button Content=&amp;quot;Zobrazit RSS&amp;quot; Click=&amp;quot;ViewRssButtonOnClick&amp;quot; Margin=&amp;quot;5&amp;quot;/&amp;gt;
        &amp;lt;TextBox Grid.Column=&amp;quot;1&amp;quot; Grid.ColumnSpan=&amp;quot;2&amp;quot; IsReadOnly=&amp;quot;True&amp;quot; Text=&amp;quot;../Files/posts.rss&amp;quot;
                   HorizontalAlignment=&amp;quot;Left&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;/&amp;gt;
        &amp;lt;ScrollViewer
            Grid.Row=&amp;quot;1&amp;quot; Grid.Column=&amp;quot;0&amp;quot; Grid.ColumnSpan=&amp;quot;2&amp;quot;
            HorizontalScrollBarVisibility=&amp;quot;Disabled&amp;quot;
            VerticalScrollBarVisibility=&amp;quot;Auto&amp;quot;&amp;gt;
            &amp;lt;ItemsControl x:Name=&amp;quot;ui_Data&amp;quot;&amp;gt;
                &amp;lt;ItemsControl.ItemTemplate&amp;gt;
                    &amp;lt;DataTemplate&amp;gt;
                        &amp;lt;Border BorderBrush=&amp;quot;Black&amp;quot; BorderThickness=&amp;quot;1&amp;quot; Margin=&amp;quot;5&amp;quot;&amp;gt;
                            &amp;lt;StackPanel&amp;gt;
                                &amp;lt;TextBlock Text=&amp;quot;{Binding Title}&amp;quot; FontWeight=&amp;quot;Bold&amp;quot;/&amp;gt;
                                &amp;lt;TextBlock Text=&amp;quot;{Binding Description}&amp;quot; TextWrapping=&amp;quot;Wrap&amp;quot;/&amp;gt;
                            &amp;lt;/StackPanel&amp;gt;
                        &amp;lt;/Border&amp;gt;
                    &amp;lt;/DataTemplate&amp;gt;
                &amp;lt;/ItemsControl.ItemTemplate&amp;gt;
            &amp;lt;/ItemsControl&amp;gt;
        &amp;lt;/ScrollViewer&amp;gt;            
            
    &amp;lt;/Grid&amp;gt;
&amp;lt;/UserControl&amp;gt;&lt;/pre&gt;

&lt;p&gt;Jednoduše se pro každou položku RSS zobrazí rámeček s titulem (tučně) a jeho popisem.&lt;/p&gt;

&lt;p&gt;Pro objektovou reprezentaci jednotlivých položek jsem si vytvořil třídu Post&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class Post
{
    public string Title { get; set; }
    public string Description { get; set; }
    public DateTime PubDate { get; set; }

    internal static Post FromFeedItem(SyndicationItem feedItem)
    {
        string description = string.Empty;

        if ( feedItem.Summary != null )
            description = feedItem.Summary.Text;
        else
            description = (( TextSyndicationContent ) feedItem.Content).Text;

        return new Post()
        {
            Title = feedItem.Title.Text,
            PubDate = feedItem.PublishDate.DateTime,
            Description = description
        };
    }
}&lt;/pre&gt;

&lt;p&gt;Třída obsahuje vlastnosti reprezentující Titul, popis a datum publikování. Kromě těchto základních vlastností obsahuje metodu FromFeedItem, která příjme objekt typu SyndicationItem (reprezentuje položku RSS kanálu), přečte potřebné hodnoty a vrátí mi můj objekt Post:&lt;/p&gt;

&lt;p&gt;Odkud, ale dostanu &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.syndication.syndicationitem.aspx" target="_blank"&gt;SyndicationItem&lt;/a&gt; objekt? Ve jmenném prostoru System.ServiceModel.Syndication (knihovna System.ServiceModel.dll) se nachází třída &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.syndication.syndicationfeed.aspx" target="_blank"&gt;SyndicationFeed&lt;/a&gt;, která reprezentuje náš RSS (Atom) kanál. Tato třída nabízí statickou metodu Load, která přebírá jako parametr objekt typu XmlReader, který má rovněž metodu Load a jedno její přetížení přebírá parametr typu Stream, který dostaneme po výsledku asynchronního volání pomocí třídy WebClient.&lt;/p&gt;

&lt;p&gt;Zavolám tedy metodu pro asynchroní stažení:&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;_webClient.OpenReadAsync(new Uri(&amp;quot;../Files/posts.rss&amp;quot;, UriKind.Relative));&lt;/pre&gt;

&lt;p&gt;Z výsledku si získám Stream a vytvořím XmlReader,&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt; XmlReader reader = XmlReader.Create(args.Result);&lt;/pre&gt;

&lt;p&gt;který potom předám jako parametr metodě Load třídy SyndicationFeed&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;SyndicationFeed feed = SyndicationFeed.Load(reader);&lt;/pre&gt;

&lt;p&gt;Pak jednoduše pomocí LINQu si projdu všechny položky a zobrazím v UI&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;var query = from feedItem in feed.Items
                  select Post.FromFeedItem(feedItem);

ui_Data.ItemsSource = query;&lt;/pre&gt;

&lt;p&gt;Výsledek si můžete prohlédnout na testovací stránce: &lt;a href="http://lukaskubis.net/Demos/Apps/WebClientViewRssSampleTestPage.html"&gt;http://lukaskubis.net/Demos/Apps/WebClientViewRssSampleTestPage.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Poznámka: Na testovací stránce používám jako zdroj dat posts.txt (nikoliv rss). Je to z důvodu, že rss není defaultně na IISku povolené a já si to momentálně sám poolit nemůžu, proto ta změna přípony.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Materiály ke stažení&lt;/h2&gt;

&lt;p&gt;Demo je ke stažení &lt;a href="http://lukaskubis.net/Demos/WebClientViewRssSample.zip" target="_blank"&gt;zde&lt;/a&gt;&lt;/p&gt;</description>
      <link>http://lukaskubis.net/post/Silverlighte28093WebClient-IIe28093zobrazeni-RSS.aspx</link>
      <author>lukask</author>
      <comments>http://lukaskubis.net/post/Silverlighte28093WebClient-IIe28093zobrazeni-RSS.aspx#comment</comments>
      <guid>http://lukaskubis.net/post.aspx?id=53e5f088-22dc-4cbf-a3e5-d216047ffb8a</guid>
      <pubDate>Sun, 19 Dec 2010 05:38:45 +1000</pubDate>
      <dc:publisher>lukask</dc:publisher>
      <pingback:server>http://lukaskubis.net/pingback.axd</pingback:server>
      <pingback:target>http://lukaskubis.net/post.aspx?id=53e5f088-22dc-4cbf-a3e5-d216047ffb8a</pingback:target>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://lukaskubis.net/trackback.axd?id=53e5f088-22dc-4cbf-a3e5-d216047ffb8a</trackback:ping>
      <wfw:comment>http://lukaskubis.net/post/Silverlighte28093WebClient-IIe28093zobrazeni-RSS.aspx#comment</wfw:comment>
      <wfw:commentRss>http://lukaskubis.net/syndication.axd?post=53e5f088-22dc-4cbf-a3e5-d216047ffb8a</wfw:commentRss>
    </item>
  </channel>
</rss>