Monday, May 13, 2024

C# Switch case With Examples



The switch statement

The switch statement selects a statement list to execute based on a pattern match with a match expression, as the following example shows:

C#

DisplayMeasurement(-4); // Output: Measured value is -4; too low. DisplayMeasurement(5); // Output: Measured value is 5. DisplayMeasurement(30); // Output: Measured value is 30; too high. DisplayMeasurement(double.NaN); // Output: Failed measurement. void DisplayMeasurement(double measurement) { switch (measurement) { case < 0.0: Console.WriteLine($"Measured value is {measurement}; too low."); break; case > 15.0: Console.WriteLine($"Measured value is {measurement}; too high."); break; case double.NaN: Console.WriteLine("Failed measurement."); break; default: Console.WriteLine($"Measured value is {measurement}."); break; } }


At the preceding example, the switch statement uses the following patterns:

The preceding example also demonstrates the default case. The default case specifies statements to execute when a match expression doesn't match any other case pattern. If a match expression doesn't match any case pattern and there's no default case, control falls through a switch statement.

switch statement executes the statement list in the first switch section whose case pattern matches a match expression and whose case guard, if present, evaluates to true. A switch statement evaluates case patterns in text order from top to bottom. The compiler generates an error when a switch statement contains an unreachable case. That is a case that is already handled by an upper case or whose pattern is impossible to match.

You can specify multiple case patterns for one section of a switch statement, as the following example shows:

C#

DisplayMeasurement(-4); // Output: Measured value is -4; out of an acceptable range. DisplayMeasurement(50); // Output: Measured value is 50. DisplayMeasurement(13); // Output: Measured value is 132; out of an acceptable range. void DisplayMeasurement(int measurement) { switch (measurement) { case < 0: case > 100: Console.WriteLine($"Measured value is {measurement}; out of an acceptable range."); break; default: Console.WriteLine($"Measured value is {measurement}."); break; } }

Within a switch statement, control can't fall through from one switch section to the next. As the examples in this section show, typically you use the break statement at the end of each switch section to pass control out of a switch statement. You can also use the return and throw statements to pass control out of a switch statement. To imitate the fall-through behavior and pass control to other switch section, you can use the goto statement.

In an expression context, you can use the switch expression to evaluate a single expression from a list of candidate expressions based on a pattern match with an expression.

Case guards

A case pattern may be not expressive enough to specify the condition for the execution of the switch section. In such a case, you can use a case guard. That is an additional condition that must be satisfied together with a matched pattern. A case guard must be a Boolean expression. You specify a case guard after the when keyword that follows a pattern, as the following example shows:

C#

DisplayMeasurements(3, 4); // Output: First measurement is 3, second measurement is 4. DisplayMeasurements(5, 5); // Output: Both measurements are valid and equal to 5. void DisplayMeasurements(int a, int b) { switch ((a, b)) { case (> 0, > 0) when a == b: Console.WriteLine($"Both measurements are valid and equal to {a}"); break; case (> 0, > 0): Console.WriteLine($"First measurement is {a}, second measurement is {b}"); break; default: Console.WriteLine("One or both measurements are not valid"); break; } }

Thursday, November 10, 2016

PanoramaControl


This is Windows 8 Style based window.

This is the Main Page content:
<Controls:MetroWindow
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="WpfApplication1.MainWindow"
    xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
    xmlns:pan="clr-namespace:PanoramaControl;assembly=PanoramaControl"
    xmlns:local="clr-namespace:WpfApplication1"
    x:Name="Window"
Title="MainWindow"
    ShowTitleBar="True"
    ShowIconOnTitleBar="false"
    ResizeMode="NoResize"
    Width="960" MinWidth="960" Height="540">
  <Window.Resources>



        <DataTemplate DataType="{x:Type local:PanoramaTileViewModel}">
            <Border x:Name="bord"
                    BorderThickness="2"
                    BorderBrush="{Binding RelativeSource={RelativeSource Mode=Self},
                        Path=Background}"
                    Background="{Binding RelativeSource={RelativeSource
                        AncestorType={x:Type pan:Panorama},
                        Mode=FindAncestor},
                        Path=TileColorPair[0]}"
                    Width="120" Height="120" Margin="0">
                <StackPanel Orientation="Horizontal">

                    <Button Command="{Binding TileClickedCommand}">
                        <Button.Template>
                            <ControlTemplate>
                                <Image x:Name="img"
                                    Source="{Binding ImageUrl}"
                                    Width="100"
                                    Height="100"
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center"
                                    ToolTip="{Binding Text}" >
                                </Image>
                                <ControlTemplate.Triggers>
                                    <DataTrigger Binding="{Binding IsDoubleWidth}" Value="True">
                                        <Setter TargetName="img"
                                            Property="HorizontalAlignment"
                                            Value="Left" />
                                        <Setter TargetName="img"
                                            Property="Margin"
                                            Value="10,0,0,0" />
                                    </DataTrigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Button.Template>
                    </Button>
                   

                    <Grid  Margin="30,0,0,0"
                            HorizontalAlignment="Left"
                            VerticalAlignment="Center">
                       
                    <Ellipse Stroke="White"
                                StrokeThickness="2"
                                Width="50"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                Height="50" Fill="Transparent"/>
                   
                        <Label x:Name="liveUpdate"
                            Content="{Binding Counter}"
                            Visibility="Collapsed"
                            HorizontalAlignment="Center"
                            HorizontalContentAlignment="Center"
                            VerticalAlignment="Center"
                            VerticalContentAlignment="Center"
                            Foreground="White"
                            FontFamily="Segoe UI"
                            FontSize="30"
                            FontWeight="DemiBold"/>
                    </Grid>

                </StackPanel>

            </Border>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource
                                AncestorType={x:Type ListBoxItem}, Mode=FindAncestor},
                                Path=IsSelected}"
                                Value="True">
                    <Setter TargetName="bord"
                            Property="BorderBrush"
                            Value="{Binding RelativeSource={RelativeSource
                                AncestorType={x:Type pan:Panorama}, Mode=FindAncestor},
                                Path=TileColorPair[1]}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding IsDoubleWidth}"
                                Value="True">
                    <Setter TargetName="bord"
                            Property="Width"
                            Value="240" />
                    <Setter TargetName="liveUpdate"
                            Property="Visibility"
                            Value="Visible" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>      
       
    </Window.Resources>
<Grid x:Name="LayoutRoot" Background="CornflowerBlue" Width="960" >
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>


        <CheckBox x:Name="chkUseSNapBackScrolling"
                    Foreground="White"
                    Content="Use Snap Back Scrolling"
                    Margin="20,10,0,10"
                    IsChecked="True"
                    VerticalAlignment="Center"
                    VerticalContentAlignment="Center"
                    HorizontalAlignment="Left"
                    HorizontalContentAlignment="Left" />

        <pan:Panorama Grid.Row="1" x:Name="pan"
                      UseSnapBackScrolling="{Binding ElementName=chkUseSNapBackScrolling, Path=IsChecked, Mode=OneWay}"
                      ItemsSource="{Binding PanoramaItems}"
                      ItemBox="120"
                      GroupHeight="360"
                      Background="Transparent" />
</Grid>
</Controls:MetroWindow>


You have to Add the images in your folder under the solution


Scroll Viewer Template Class

[TemplatePart(Name = "PART_ScrollViewer", Type = typeof(ScrollViewer))]
    public class Panorama : ItemsControl
    {
        #region Data
        private ScrollViewer sv;
        private Point scrollTarget;
        private Point scrollStartPoint;
        private Point scrollStartOffset;
        private Point previousPoint;
        private Vector velocity;
        private double friction;
        private DispatcherTimer animationTimer = new DispatcherTimer(DispatcherPriority.DataBind);
        private static int PixelsToMoveToBeConsideredScroll = 5;
        private static int PixelsToMoveToBeConsideredClick = 2;
        private Random rand = new Random(DateTime.Now.Millisecond);
        private bool _mouseDownFlag;
        private Cursor _savedCursor;
        #endregion

        #region Ctor
        public Panorama()
        {
            friction = 0.85;

            animationTimer.Interval = new TimeSpan(0, 0, 0, 0, 20);
            animationTimer.Tick += new EventHandler(HandleWorldTimerTick);
            animationTimer.Start();

            TileColors = new Brush[] {
                new SolidColorBrush(Color.FromRgb((byte)111,(byte)189,(byte)69)),
                new SolidColorBrush(Color.FromRgb((byte)75,(byte)179,(byte)221)),
                new SolidColorBrush(Color.FromRgb((byte)65,(byte)100,(byte)165)),
                new SolidColorBrush(Color.FromRgb((byte)225,(byte)32,(byte)38)),
                new SolidColorBrush(Color.FromRgb((byte)128,(byte)0,(byte)128)),
                new SolidColorBrush(Color.FromRgb((byte)0,(byte)128,(byte)64)),
                new SolidColorBrush(Color.FromRgb((byte)0,(byte)148,(byte)255)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)0,(byte)199)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)135,(byte)15)),
                new SolidColorBrush(Color.FromRgb((byte)45,(byte)255,(byte)87)),
                new SolidColorBrush(Color.FromRgb((byte)127,(byte)0,(byte)55))
   
            };

            ComplimentaryTileColors = new Brush[] {
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)255,(byte)255)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)255,(byte)255)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)255,(byte)255)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)255,(byte)255)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)255,(byte)255)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)255,(byte)255)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)255,(byte)255)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)255,(byte)255)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)255,(byte)255)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)255,(byte)255)),
                new SolidColorBrush(Color.FromRgb((byte)255,(byte)255,(byte)255))
            };

        }

        static Panorama()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Panorama), new FrameworkPropertyMetadata(typeof(Panorama)));
        }
        #endregion

        #region Properties
        public double Friction
        {
            get { return 1.0 - friction; }
            set { friction = Math.Min(Math.Max(1.0 - value, 0), 1.0); }
        }

        public List<Brush> TileColorPair
        {
            get
            {
                int idx = rand.Next(TileColors.Length);
                return new List<Brush>() { TileColors[idx], ComplimentaryTileColors[idx] };
            }
        }

        #region DPs


        #region ItemBox

        public static readonly DependencyProperty ItemBoxProperty =
            DependencyProperty.Register("ItemBox", typeof(double), typeof(Panorama),
                new FrameworkPropertyMetadata((double)120.0));


        public double ItemBox
        {
            get { return (double)GetValue(ItemBoxProperty); }
            set { SetValue(ItemBoxProperty, value); }
        }

        #endregion

        #region GroupHeight

        public static readonly DependencyProperty GroupHeightProperty =
            DependencyProperty.Register("GroupHeight", typeof(double), typeof(Panorama),
                new FrameworkPropertyMetadata((double)640.0));


        public double GroupHeight
        {
            get { return (double)GetValue(GroupHeightProperty); }
            set { SetValue(GroupHeightProperty, value); }
        }

        #endregion



        #region HeaderFontSize

        public static readonly DependencyProperty HeaderFontSizeProperty =
            DependencyProperty.Register("HeaderFontSize", typeof(double), typeof(Panorama),
                new FrameworkPropertyMetadata((double)30.0));

        public double HeaderFontSize
        {
            get { return (double)GetValue(HeaderFontSizeProperty); }
            set { SetValue(HeaderFontSizeProperty, value); }
        }

        #endregion



        #region HeaderFontColor

        public static readonly DependencyProperty HeaderFontColorProperty =
            DependencyProperty.Register("HeaderFontColor", typeof(Brush), typeof(Panorama),
                new FrameworkPropertyMetadata((Brush)Brushes.White));

        public Brush HeaderFontColor
        {
            get { return (Brush)GetValue(HeaderFontColorProperty); }
            set { SetValue(HeaderFontColorProperty, value); }
        }

        #endregion

        #region HeaderFontFamily

        public static readonly DependencyProperty HeaderFontFamilyProperty =
            DependencyProperty.Register("HeaderFontFamily", typeof(FontFamily), typeof(Panorama),
                new FrameworkPropertyMetadata((FontFamily)new FontFamily("Segoe UI")));

        public FontFamily HeaderFontFamily
        {
            get { return (FontFamily)GetValue(HeaderFontFamilyProperty); }
            set { SetValue(HeaderFontFamilyProperty, value); }
        }

        #endregion

        #region TileColors

        public static readonly DependencyProperty TileColorsProperty =
            DependencyProperty.Register("TileColors", typeof(Brush[]), typeof(Panorama),
                new FrameworkPropertyMetadata((Brush[])null));

        public Brush[] TileColors
        {
            get { return (Brush[])GetValue(TileColorsProperty); }
            set { SetValue(TileColorsProperty, value); }
        }

        #endregion

        #region ComplimentaryTileColors

        public static readonly DependencyProperty ComplimentaryTileColorsProperty =
            DependencyProperty.Register("ComplimentaryTileColors", typeof(Brush[]), typeof(Panorama),
                new FrameworkPropertyMetadata((Brush[])null));

        public Brush[] ComplimentaryTileColors
        {
            get { return (Brush[])GetValue(ComplimentaryTileColorsProperty); }
            set { SetValue(ComplimentaryTileColorsProperty, value); }
        }

        #endregion

        #region UseSnapBackScrolling

        public static readonly DependencyProperty UseSnapBackScrollingProperty =
            DependencyProperty.Register("UseSnapBackScrolling", typeof(bool), typeof(Panorama),
                new FrameworkPropertyMetadata((bool)true));

        public bool UseSnapBackScrolling
        {
            get { return (bool)GetValue(UseSnapBackScrollingProperty); }
            set { SetValue(UseSnapBackScrollingProperty, value); }
        }

        #endregion

        #endregion

        #endregion

        #region Private Methods

        private void DoStandardScrolling()
        {
            sv.ScrollToHorizontalOffset(scrollTarget.X);
            sv.ScrollToVerticalOffset(scrollTarget.Y);
            scrollTarget.X += velocity.X;
            scrollTarget.Y += velocity.Y;
            velocity *= friction;
        }


        private void HandleWorldTimerTick(object sender, EventArgs e)
        {
            var prop = DesignerProperties.IsInDesignModeProperty;
            bool isInDesignMode = (bool)DependencyPropertyDescriptor.FromProperty(prop,
                typeof(FrameworkElement)).Metadata.DefaultValue;

            if (isInDesignMode)
                return;


            if (IsMouseCaptured)
            {
                Point currentPoint = Mouse.GetPosition(this);
                velocity = previousPoint - currentPoint;
                previousPoint = currentPoint;
            }
            else
            {
                if (velocity.Length > 1)
                {
                    DoStandardScrolling();
                }
                else
                {
                    if (UseSnapBackScrolling)
                    {
                        int mx = (int)sv.HorizontalOffset % (int)ActualWidth;
                        if (mx == 0)
                            return;
                        int ix = (int)sv.HorizontalOffset / (int)ActualWidth;
                        double snapBackX = mx > ActualWidth / 2 ? (ix + 1) * ActualWidth : ix * ActualWidth;
                        sv.ScrollToHorizontalOffset(sv.HorizontalOffset + (snapBackX - sv.HorizontalOffset) / 4.0);
                    }
                    else
                    {
                        DoStandardScrolling();
                    }
                }
            }
        }
        #endregion

        #region Overrides


        public override void OnApplyTemplate()
        {
            sv = (ScrollViewer)Template.FindName("PART_ScrollViewer", this);
            base.OnApplyTemplate();
        }


        protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            if (sv.IsMouseOver)
            {
                _mouseDownFlag = true;

                // Save starting point, used later when determining how much to scroll.
                scrollStartPoint = e.GetPosition(this);
                scrollStartOffset.X = sv.HorizontalOffset;
                scrollStartOffset.Y = sv.VerticalOffset;
            }

            base.OnPreviewMouseLeftButtonDown(e);
        }

        protected override void OnPreviewMouseMove(MouseEventArgs e)
        {
            if (_mouseDownFlag)
            {
                Point currentPoint = e.GetPosition(this);

                // Determine the new amount to scroll.
                Point delta = new Point(scrollStartPoint.X - currentPoint.X, scrollStartPoint.Y - currentPoint.Y);

                if (Math.Abs(delta.X) > PixelsToMoveToBeConsideredScroll ||
                    Math.Abs(delta.Y) > PixelsToMoveToBeConsideredScroll)
                {
                    scrollTarget.X = scrollStartOffset.X + delta.X;
                    scrollTarget.Y = scrollStartOffset.Y + delta.Y;

                    // Scroll to the new position.
                    sv.ScrollToHorizontalOffset(scrollTarget.X);
                    sv.ScrollToVerticalOffset(scrollTarget.Y);

                    if (!this.IsMouseCaptured)
                    {
                        if ((sv.ExtentWidth > sv.ViewportWidth) ||
                            (sv.ExtentHeight > sv.ViewportHeight))
                        {
                            _savedCursor = this.Cursor;
                            this.Cursor = Cursors.ScrollWE;
                        }

                        this.CaptureMouse();
                    }
                }
            }

            base.OnPreviewMouseMove(e);
        }

        protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            bool mouseDownFlag = _mouseDownFlag;
            // mouse move events may trigger while inside this handler.
            _mouseDownFlag = false;

            if (this.IsMouseCaptured)
            {
                // scroll action stopped
                this.Cursor = _savedCursor;
                this.ReleaseMouseCapture();
            }
            else if (mouseDownFlag)
            {
                // click action stopped
            }

            _savedCursor = null;

            base.OnPreviewMouseLeftButtonUp(e);
        }
        #endregion

    }


Panorama Group Control

public class PanoramaGroup
    {
        public PanoramaGroup(string header, ICollectionView tiles)
        {
            this.Header = header;
            this.Tiles = tiles;
        }

        public string Header { get; private set; }
        public ICollectionView Tiles { get; private set; }
    }

Group With Converter Class

 public class PanoramaGroupWidthConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            double itemBox = double.Parse(values[0].ToString());
            double groupHeight = double.Parse(values[1].ToString());

            double ratio = groupHeight / itemBox;
            ListBox list = (ListBox)values[2];


            double width = Math.Ceiling(list.Items.Count / ratio);
            width *= itemBox;
            if (width < itemBox)
                return itemBox;
            else
                return width;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

Simple Commad Class

public class SimpleCommand<T1, T2> : ICommand
    {
        private Func<T1, bool> canExecuteMethod;
        private Action<T2> executeMethod;

        public SimpleCommand(Func<T1, bool> canExecuteMethod, Action<T2> executeMethod)
        {
            this.executeMethod = executeMethod;
            this.canExecuteMethod = canExecuteMethod;
        }

        public SimpleCommand(Action<T2> executeMethod)
        {
            this.executeMethod = executeMethod;
            this.canExecuteMethod = (x) => { return true; };
        }


        public bool CanExecute(T1 parameter)
        {
            if (canExecuteMethod == null) return true;
            return canExecuteMethod(parameter);
        }

        public void Execute(T2 parameter)
        {
            if (executeMethod != null)
            {
                executeMethod(parameter);
            }
        }

        public bool CanExecute(object parameter)
        {
            return CanExecute((T1)parameter);
        }

        public void Execute(object parameter)
        {
            Execute((T2)parameter);
        }

#if SILVERLIGHT
        /// <summary>
        /// Occurs when changes occur that affect whether the command should execute.
        /// </summary>
        public event EventHandler CanExecuteChanged;
#else
        /// <summary>
        /// Occurs when changes occur that affect whether the command should execute.
        /// </summary>
        public event EventHandler CanExecuteChanged
        {
            add
            {
                if (canExecuteMethod != null)
                {
                    CommandManager.RequerySuggested += value;
                }
            }

            remove
            {
                if (canExecuteMethod != null)
                {
                    CommandManager.RequerySuggested -= value;
                }
            }
        }
#endif



        /// <summary>
        /// Raises the <see cref="CanExecuteChanged" /> event.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
            Justification = "The this keyword is used in the Silverlight version")]
        [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate",
            Justification = "This cannot be an event")]
        public void RaiseCanExecuteChanged()
        {
#if SILVERLIGHT
            var handler = CanExecuteChanged;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
#else
            CommandManager.InvalidateRequerySuggested();
#endif
        }
    }
}

Message Box Service and Interface calsss

  public interface IMessageBoxService
    {
        void ShowMessage(string message);
    }

    public class MessageBoxService : IMessageBoxService
    {
        public void ShowMessage(string message)
        {
            MessageBox.Show(message);
        }
    }

Notification Changed Class

  #region INPC

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        #endregion


Main View Model Class

 public class MainWindowViewModel : INPCBase
    {
        private Random rand = new Random(DateTime.Now.Millisecond);
        private List<DummyTileData> dummyData = new List<DummyTileData>();
        private IMessageBoxService messageBoxService;



        public MainWindowViewModel(IMessageBoxService messageBoxService)
        {
            this.messageBoxService = messageBoxService;

            //create some dummy data
            dummyData.Add(new DummyTileData("Add", @"Images/Add.png"));
            dummyData.Add(new DummyTileData("Adobe", @"Images/Adobe.png"));
            dummyData.Add(new DummyTileData("Android", @"Images/Android.png"));
            dummyData.Add(new DummyTileData("Author", @"Images/Author.png"));
            dummyData.Add(new DummyTileData("Blogger", @"Images/Blogger.png"));
            dummyData.Add(new DummyTileData("Copy", @"Images/Copy.png"));
            dummyData.Add(new DummyTileData("Delete", @"Images/Delete.png"));
            dummyData.Add(new DummyTileData("Digg", @"Images/Digg.png"));
            dummyData.Add(new DummyTileData("Edit", @"Images/Edit.png"));
            dummyData.Add(new DummyTileData("Facebook", @"Images/Facebook.png"));
            dummyData.Add(new DummyTileData("GMail", @"Images/GMail.png"));
            dummyData.Add(new DummyTileData("RSS", @"Images/RSS.png"));
            dummyData.Add(new DummyTileData("Save", @"Images/Save.png"));
            dummyData.Add(new DummyTileData("Search", @"Images/Search.png"));
            dummyData.Add(new DummyTileData("Trash", @"Images/Trash.png"));
            dummyData.Add(new DummyTileData("Twitter", @"Images/Twitter.png"));
            dummyData.Add(new DummyTileData("VisualStudio", @"Images/VisualStudio.png"));
            dummyData.Add(new DummyTileData("Wordpress", @"Images/Wordpress.png"));
            dummyData.Add(new DummyTileData("Yahoo", @"Images/Yahoo.png"));
            dummyData.Add(new DummyTileData("YouTube", @"Images/YouTube.png"));

            //Great some dummy groups
            List<PanoramaGroup> data = new List<PanoramaGroup>();
            List<PanoramaTileViewModel> tiles = new List<PanoramaTileViewModel>();

            for (int i = 0; i < 4; i++)
            {
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(true));

                tiles.Add(CreateTile(true));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));

                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));

                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
                tiles.Add(CreateTile(false));
            }

            data.Add(new PanoramaGroup("Settings",
                CollectionViewSource.GetDefaultView(tiles)));

            PanoramaItems = data;

        }


        private PanoramaTileViewModel CreateTile(bool isDoubleWidth)
        {
            DummyTileData dummyTileData = dummyData[rand.Next(dummyData.Count)];
            return new PanoramaTileViewModel(messageBoxService,
                dummyTileData.Text, dummyTileData.ImageUrl, isDoubleWidth);
        }


        private IEnumerable<PanoramaGroup> panoramaItems;

        public IEnumerable<PanoramaGroup> PanoramaItems
        {
            get { return this.panoramaItems; }

            set
            {
                if (value != this.panoramaItems)
                {
                    this.panoramaItems = value;
                    NotifyPropertyChanged("CompanyName");
                }
            }
        }
    }




    public class DummyTileData
    {
        public string Text { get; private set; }
        public string ImageUrl { get; private set; }

        public DummyTileData(string text, string imageUrl)
        {
            this.Text = text;
            this.ImageUrl = imageUrl;
        }
    }


Panorama Tile View Model Class

public class PanoramaTileViewModel : INPCBase
    {
        private IMessageBoxService messageBoxService;
        private Timer liveUpdateTileTimer = new Timer();

        public PanoramaTileViewModel(IMessageBoxService messageBoxService, string text, string imageUrl, bool isDoubleWidth)
        {
            if (isDoubleWidth)
            {
                liveUpdateTileTimer.Interval = 1000;
                liveUpdateTileTimer.Elapsed += new ElapsedEventHandler(LiveUpdateTileTimer_Elapsed);
                liveUpdateTileTimer.Start();
            }


            this.messageBoxService = messageBoxService;
            this.Text = text;
            this.ImageUrl = imageUrl;
            this.IsDoubleWidth = isDoubleWidth;
            this.TileClickedCommand = new SimpleCommand<object, object>(ExecuteTileClickedCommand);
        }

        void LiveUpdateTileTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (Counter < 10)
                Counter++;
            else
                Counter = 0;
            NotifyPropertyChanged("Counter");
        }

        public int Counter { get; set; }
        public string Text { get; private set; }
        public string ImageUrl { get; private set; }
        public bool IsDoubleWidth { get; private set; }
        public ICommand TileClickedCommand { get; private set; }

        public void ExecuteTileClickedCommand(object parameter)
        {
            messageBoxService.ShowMessage(string.Format("you clicked {0}", this.Text));
        }
    }