Tuesday, December 27, 2011

Using LINQ To SQL CompiledQuery


CompliedQuery increase performance by compiling the query one time and executing it several times with different parameters.

With CompliedQuery , you compile your query once and store it somewhere for later usage. This is achieved by static CompliedQuery.Compile method.

It provides for compilation and caching of queries for reuse.
To compile the query, we have to use the CompiledQuery.Compile method. This method takes an argument list as input and a result type.

Below is simple Example.

The following example compiles and then invokes a query that  returns a List of employees where employeeid=1.

public static Func<TestDataContext, IEnumerable<Employee>> GetEmployeeList
        {
            get
            {
                return CompiledQuery.Compile<TestDataContext, IEnumerable<Employee>>
                    ((TestDataContext context) => context.Employees.Where<Employee>(x => x.EmployeeID== 1));
            }
        }

In above code, i created DBML DataContext named TestDataContext that contains all tables.

I have created class named Employee to use in result set.


Tips to Improve LINQ to SQL Performance

Please follow below link.

LINQToSQLPerformance


Convert UIElement to Image in WPF

FramewrokElement class Provides a framework-level set of properties, events, and methods for Windows Presentation Foundation (WPF) elements.

FrameworkElement (FE) derives from UIElement.

UIElement  is a base class for WPF core level implementations building on Windows Presentation Foundation (WPF) elements and basic presentation characteristics.

Background

In this article, i am going to explain how to convert UIElement to ImageSource.
RenderTargetBitmap property of System.Windows.Media used to convert visual object into bitmap.
DrawingVisual used to render vector graphics.

Go Through code

I have created TreeView, and binds  parent and child treeitems from Collections.

Step 1 :Create Models.
Area.cs
  public class Area
    {
        public string AreaName { get; set; }
        public string Description { get; set; }        
    } 
This class is for child nodes.

Location.cs
  public class Location
    {
        public string LocationName { get; set; }
        public List<Area> AreaList { get; set; }      
    } 
This class contains properties for Parent tree nodes and child node collections for each parent nodes.

Step 2 :Create ViewModel to bind Collections.

MainViewmodel.cs
  public class MainViewmodel
    {
        private ObservableCollection<Location> _locations;
        public ObservableCollection<Location> Locations
        {
            get { return _locations; }
            set { _locations = value; }
        }
        public MainViewmodel()
        {
            Locations = new ObservableCollection<Location>();
            BindLocationList();
        }
        List<Area> GetAreaList()
        {
            List<Area> returnList = new List<Area>();
           returnList.Add(new Area() { AreaName = "Kankaria", 
                      Description = "The state has witnessed all-round progress in every field. });
           returnList.Add(new Area() { AreaName = "Swapnasrusthi", 
                      Description = "The state has witnessed all-round progress in every field. });
           returnList.Add(new Area() { AreaName = "Scien city", 
                      Description = "The state has witnessed all-round progress in every field.});

           returnList.Add(new Area() { AreaName = "Lal quila", 
                      Description = "The state has witnessed all-round progress in every field. });
           returnList.Add(new Area() { AreaName = "lake view", 
                      Description = "The state has witnessed all-round progress in every field. });
           returnList.Add(new Area() { AreaName = "Shilalekh", 
                      Description = "The state has witnessed all-round progress in every field. }); 
           returnList.Add(new Area() { AreaName = "Girnar", 
                      Description = "The state has witnessed all-round progress in every field. It has
           returnList.Add(new Area() { AreaName = "Zoo", 
                      Description = "The state has witnessed all-round progress in every field. });
           returnList.Add(new Area() { AreaName = "chandani chowk", 
                      Description = "The state has witnessed all-round progress in every field.});
           returnList.Add(new Area() { AreaName = "Akshradham", 
                      Description = "The state has witnessed all-round progress in every field. }); 
           returnList.Add(new Area() { AreaName = "Qutub minar", 
                      Description = "The state has witnessed all-round progress in every field. }); 
           return returnList;
        }
        void BindLocationList()
        {
            List<Area> areaList = GetAreaList();
            List<Location> locationList = new List<Location>();
            locationList.Add(new Location() { LocationName = "Ahmedabad", AreaList = areaList.Take(3).ToList() });
            locationList.Add(new Location() { LocationName = "Jamnagar", AreaList = areaList.Skip(3).Take(2).ToList() });
            locationList.Add(new Location() { LocationName = "Junagadh", AreaList = areaList.Skip(5).Take(3).ToList() });
            locationList.Add(new Location() { LocationName = "Delhi", AreaList = areaList.Skip(8).Take(3).ToList() });
            Locations = new ObservableCollection<Location>(locationList);
        }
    } 
In above code, i have created ObservableCollection of Locations which provides notification on add/edit items.
bind locations and areas within location.

Step 3 : Create Templates for TreeView.

MainWindow.xaml
 <DataTemplate x:Key="AreaDataTemplate">
            <StackPanel Orientation="Vertical">
                <TextBlock Text="{Binding AreaName}"
                           VerticalAlignment="Center"
                           Margin="5"
                           Style="{StaticResource TextBlockStyle2}" />
                <TextBlock Text="{Binding Description}"
                           Width="300"
                           Style="{StaticResource TextBlockStyle2}" />
            </StackPanel>
        </DataTemplate> 
 
DataTemplate provides you with great flexibility to define the presentation of your data.
DataTemplate  give you a very flexible and powerful solution to replace the visual appearance of a data item in a control like ListBox, ComboBox or ListView.
Bind child tree items and present layout of child nodes in treeview.
 <HierarchicalDataTemplate x:Key="LocationTemplate"
                                  ItemsSource="{Binding AreaList}"
                                  ItemTemplate="{StaticResource AreaDataTemplate}">
            <TextBlock Text="{Binding LocationName}"
                       Margin="5 5 10 10"
                       Style="{StaticResource TextBlockStyle}" />
        </HierarchicalDataTemplate>

HierarchicalDataTemplate Represents a DataTemplat  that supports HeaderedItemControl, such as TreeViewItems.  
Bind ItmesSource to AreaList(for child TreeViewItems) and ItemTemplate to child DataTemplate resource key.

Step 4 : Place TreeView into Window.
 
MainWindow.xaml
 <Grid Grid.Row="1"
                      MaxHeight="250">
                    <TreeView ScrollViewer.CanContentScroll="True"
                              BorderThickness="0"
                              Background="#FFF"
                              ItemsSource="{Binding Locations}"
                              ItemTemplate="{DynamicResource LocationTemplate}"
                              x:Name="LocationTreeView" />
                </Grid> 
 
I have placed TreeView within Grid and sets its CanContentScroll property to true, which adds scroll when treenode expands if height exceeds 250.
Bind ItemsSource with Locations and set ItemTemplate to HierarchicalDataTemplate.

Step 5 : Place Button, which Excutes code to convert UIElement to ImageSource.
Grid Grid.Row="1">
                <Button Content="Generate Image"
                        x:Name="convert"
                        Width="100"
                        Grid.Row="1"
                        Height="25"
                        Click="convert_Click" />
            </Grid>

Step 6 : Place Image into window to set Source from UIElement.
<Grid Grid.Row="2"
                  MaxWidth="400"
                  MinHeight="400">
                <Image x:Name="displayImage"
                       Grid.Row="2"
                       Stretch="Fill"
                       Margin="0 0 0 30" />
            </Grid>

Step 7 : Create Method to find UIElement from parent UIElement.
   private ScrollViewer GetTemplateChildByName(DependencyObject parent)
        {
            int childnum = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < childnum; i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);
                if (child is ScrollViewer)
                {
                    return child as ScrollViewer;
                }
                else
                {
                    var s = GetTemplateChildByName(child);
                    if (s != null)
                        return s;
                }
            }
            return null;
        } 
 
This method find UIElement within parent UIElement. it will find child element using GetChild method of VisualTreeHelper.
VisualTreeHelper provides utility methods that perform common tasks involving nodes in a visual tree.
VisualTreeHelper.GetChild method Returns the child visual object from the specified collection index within a specified parent.
I have write this method for find ScrollViewer within TreeView.

Step 8 : Write code to Convert ImageSource from UIElement.
private void convert_Click(object sender, RoutedEventArgs e)
        {
            ScrollViewer scroll = GetTemplateChildByName(LocationTreeView);
            if (scroll != null)
            {
                ItemsPresenter item = scroll.Content as ItemsPresenter;
                double width = item.ActualWidth;
                double height = item.ActualHeight;
                RenderTargetBitmap bmpCopied =  
       new RenderTargetBitmap((int)Math.Round(width), (int)Math.Round(height), 100, 100, PixelFormats.Default);
                DrawingVisual drawingVisual = new DrawingVisual();
                using (DrawingContext drawingContext = drawingVisual.RenderOpen())
                {
                    VisualBrush visualBrush = new VisualBrush(item);
                    drawingContext.DrawRectangle(visualBrush, null, new Rect(new Point(), new Size(width, height)));
                }
                bmpCopied.Render(drawingVisual);
                displayImage.Source = bmpCopied;
            }
        }

In Button click event handler, i wrote code to convert TreeView content into ImageSource.

First find ScrollViewer within TreeView.

after that get ItemPresenter from ScrollViewer Content, because we need to convert full expandable TreeView into ImageSource.

if you get ActualHeight of TreeView/ScrollViewer it will gives only visible area height, so it will convert only visible area to image not scroll area.

To convert hided scoll area as well as visible area, you have to get ScrollViewer Content as a ItemPresenter and Draw Image using ItemPresenter element and its ActualWidth/ActualHeight property.

Conclusion

when you work with ScrollViewer,
Always use its content area in width and height calculation.
it will gives ActualHeight/ActualWidth of content within ScrollViewer.

 You Can Download Source From : Convert UIElement to ImageSource

Thursday, December 22, 2011

Customize TabControl in Silverlight (create tab control with side bar)


The TabControl control brings flexibility to your websites navigation by allowing you to create a set of Tabs that can be used to organize page content.


TabControl is Silverlight toolkit control, so first you have to install latest toolkit download from http://www.silverlight.net
After installing toolkit you will see TabControl in your toolbox. 

In Silverlight Development Environment ,it is difficult to change the layout of TabControl.

Sometimes we have requirement to customize our tab control layout, So we need to create custom template for TabControl and TabItems.

In this article we walk-through how to Create Sidebar control with TabControl on right of side bar and show/hide side bar.

Go Through Code


Step 1 : Create Custom ScalePanel Control for Side bar

ScalePanel.cs 
  public class ScalePanel : Panel
    {
        #region ScaleXProperty
        public Double ScaleX
        {
            get { return (Double)GetValue(ScaleXProperty); }
            set { SetValue(ScaleXProperty, value); }
        }
        public static readonly DependencyProperty ScaleXProperty =
            DependencyProperty.Register("ScaleX", typeof(Double),
            typeof(ScalePanel),  
           new PropertyMetadata(1.0d, new PropertyChangedCallback(ScaleXChanged)));

        public static void ScaleXChanged(DependencyObject sender, 
               DependencyPropertyChangedEventArgs e)
        {
            ScalePanel obj = sender as ScalePanel;
            if (obj != null)
            {
                obj.OnScaleXChanged(e);
            }
        }
        private void OnScaleXChanged(DependencyPropertyChangedEventArgs e)
        {
            InvalidateMeasure();
        }
        #endregion

        #region ScaleYProperty
        public Double ScaleY
        {
            get { return (Double)GetValue(ScaleYProperty); }
            set { SetValue(ScaleYProperty, value); }
        }

        public static readonly DependencyProperty ScaleYProperty =
            DependencyProperty.Register("ScaleY", typeof(Double), 
            typeof(ScalePanel), 
            new PropertyMetadata(1.0d, new PropertyChangedCallback(ScaleYChanged)));

        public static void ScaleYChanged(DependencyObject sender, 
                 DependencyPropertyChangedEventArgs e)
        {
            ScalePanel obj = sender as ScalePanel;
            if (obj != null)
            {
                obj.OnScaleYChanged(e);
            }
        }

        private void OnScaleYChanged(DependencyPropertyChangedEventArgs e)
        {
            InvalidateMeasure();
        }
        #endregion

        protected override Size MeasureOverride(Size availableSize)
        {
            Size finalSize = new Size();

            if (Children.Any())
            {
                UIElement child = Children.First();
                child.Measure(availableSize);
                finalSize.Width = Math.Min(child.DesiredSize.Width, availableSize.Width);
                finalSize.Height = Math.Min(child.DesiredSize.Height, availableSize.Height);
            }

            finalSize.Width = finalSize.Width * ScaleX;
            finalSize.Height = finalSize.Height * ScaleY;

            return finalSize;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            if (Children.Any())
            {
                UIElement child = Children.First();
                child.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
            }

            return finalSize;
        }
    } 
In this code you notice that ScaleXProperty and ScaleYProperty dependency property defined.
So we arise question what is DepenencyProperty ? and why we need to use.
I give you brief description to aware about DepenencyProperty.
DependencyProperty
Dependency Property is like any other property but can hold a default value, with built in mechanism for property value validation and automatic notification for changes in property value ( for anyone listening to property value - especially UI) and any binding in Silverlight is to binded to a Dependency Property.

Dependency properties are properties that are registered with the Silverlight property system by calling the DependencyProperty.Register method.

The purpose of dependency properties is to provide a way to compute the value of a property based on the value of other inputs.

DependencyObject defines the base class that can register and own a dependency property.
You can go into detail with example to follow this link.

so both scaleY and ScaleY property scales the panel with content.

There are two override method defined, One is MeasureOverride and other is ArrangeOverride.

  • MeasureOverride
Provides the behavior for the Measure pass of Silverlight layout.
This method has a default implementation that performs built-in layout for most Silverlight FrameworkElement classes.
So in our code it customize the Measure pass logic for a custom panel implementation and it perform following task.
   1. Iterates over children.
   2.  For each child, calls Measure, using a Size that makes sense based on how the panel logic treats the  number of children and its own known size limit
   3.   Returns its size (determines it needs during layout, based on its calculations of child object allotted sizes)
You can go into detail with example to follow this link   
  • ArrangeOverride
Provides the behavior for the Arrange pass of Silverlight layout.
In simple it Arranges the content of a FrameworkElement.
ArrangeOverride to customize the Arrange pass
1.Iterates over children.
2.For each child, calls Arrange, using a Rect where Height and Width are based on DesiredSize, and X and Y are based on logic that is specific to the panel.
3.Returns its size (The actual size that is used after the element is arranged in layout)
For Silverlight/WPF, the technique by which elements are sized and positioned in a layout is divided into two steps: a Measure pass, and then an Arrange pass.
You can go into detail with example to follow this link

Step 2: Add namespace in your UserControl.
  xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
  xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"       
  xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
  xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
 
1.  System.windows.Interactivity provides Event Trigger on control to perform action on event fire.
2.  Interaction provides ControlStoryboardAction with EventTrigger.
      3.  Toolkit is used for Transform Layout of Control.

Step 3: Create Template for TabItem.
 <ControlTemplate x:Key="RightMenuTabItem"
                         TargetType="sdk:TabItem">
            <Border>
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal" />
                        <VisualState x:Name="MouseOver">
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetName="TabHeaderHighlightBackgroundBorder"
                                                 Storyboard.TargetProperty="Opacity"
                                                 To="1"
                                                 Duration="0:0:0.25" />
                                <ObjectAnimationUsingKeyFrames Duration="00:00:00.25"
                                                               Storyboard.TargetName="ContControl"
                                                               Storyboard.TargetProperty="Foreground">
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00">
                                        <DiscreteObjectKeyFrame.Value>
                                            <Color>Black</Color>
                                        </DiscreteObjectKeyFrame.Value>
                                    </DiscreteObjectKeyFrame>
                                </ObjectAnimationUsingKeyFrames>
                                <ObjectAnimationUsingKeyFrames Duration="00:00:00.25"
                                                               Storyboard.TargetName="TabHeaderBackgroundBorder"
                                                               Storyboard.TargetProperty="BorderThickness">
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00">
                                        <DiscreteObjectKeyFrame.Value>
                                            <Thickness>1 1 0 0</Thickness>
                                        </DiscreteObjectKeyFrame.Value>
                                    </DiscreteObjectKeyFrame>
                                </ObjectAnimationUsingKeyFrames>
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                    <VisualStateGroup x:Name="SelectionStates">
                        <VisualState x:Name="Unselected" />
                        <VisualState x:Name="Selected">
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetName="TabHeaderSelectedBackgroundBorder"
                                                 Storyboard.TargetProperty="Opacity"
                                                 To="1"
                                                 Duration="0:0:0.25" />
                                <ObjectAnimationUsingKeyFrames Duration="00:00:00.25"
                                                               Storyboard.TargetName="ContControl"
                                                               Storyboard.TargetProperty="Foreground">
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00">
                                        <DiscreteObjectKeyFrame.Value>
                                            <Color>Black</Color>
                                        </DiscreteObjectKeyFrame.Value>
                                    </DiscreteObjectKeyFrame>
                                </ObjectAnimationUsingKeyFrames>
                                <ObjectAnimationUsingKeyFrames Duration="00:00:00.25"
                                                               Storyboard.TargetName="TabHeaderBackgroundBorder"
                                                               Storyboard.TargetProperty="BorderThickness">
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00">
                                        <DiscreteObjectKeyFrame.Value>
                                            <Thickness>1 1 0 0</Thickness>
                                        </DiscreteObjectKeyFrame.Value>
                                    </DiscreteObjectKeyFrame>
                                </ObjectAnimationUsingKeyFrames>
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <toolkit:LayoutTransformer x:Name="layoutTransformer">
                    <toolkit:LayoutTransformer.LayoutTransform>
                        <RotateTransform Angle="90" />
                    </toolkit:LayoutTransformer.LayoutTransform>
                    <Border x:Name="TabHeaderBackgroundBorder"
                            RenderTransformOrigin="0.5,0.5"
                            BorderBrush="Black"
                            BorderThickness="1,1,0,1"
                            Background="{StaticResource TabHeaderBackground}">
                        <Grid>
                            <Border x:Name="TabHeaderHighlightBackgroundBorder"
                                    Opacity="0"
                                    Background="{StaticResource TabHeaderHighlightBackground}" />
                            <Border x:Name="TabHeaderSelectedBackgroundBorder"
                                    Opacity="0"
                                    Background="{StaticResource TabHeaderSelectedBackground}" />
                            <ContentControl Content="{TemplateBinding Header}"
                                            HorizontalContentAlignment="Center"
                                            VerticalContentAlignment="Center"
                                            Margin="16,10,16,10"
                                            FontFamily="Verdana"
                                            FontSize="15"
                                            Foreground="White"
                                            FontWeight="Bold"
                                            Cursor="Hand"
                                            x:Name="ContControl" />
                        </Grid>
                    </Border>
                </toolkit:LayoutTransformer>
            </Border>
        </ControlTemplate>

Above control template provides style and template for TabItems.

VisualStateManager Manages states and the logic for transitioning between states for controls.

Created customStates which defines MouseOver, Normal and Selected visualstate object for each TabItmes. When user put mouse over the tab items, its background color changes to yellow and on mouse leave it will back to red color.
 
 <toolkit:LayoutTransformer.LayoutTransform>
                        <RotateTransform Angle="90" />
                    </toolkit:LayoutTransformer.LayoutTransform> 
 
 
Above snippet rotate TabItems from horizontal to Vertiacal.
 
Step 4 : Create Template for TabControl.
 <ControlTemplate x:Key="RightMenuTabControl"
                         TargetType="sdk:TabControl">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <Grid Grid.Column="0">
                    <Button Template="{StaticResource PolygonButton}"
                            x:Name="CloseCall"
                            Cursor="Hand">
                        <Polyline HorizontalAlignment="Center"
                                  VerticalAlignment="Center"
                                  Stroke="Black"
                                  StrokeThickness="2"
                                  Points="0,0 4,4 0,8" />
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Click">
                                <ei:ControlStoryboardAction ControlStoryboardOption="Play">
                                    <ei:ControlStoryboardAction.Storyboard>
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="TabContentScalePanel"
                                                             Storyboard.TargetProperty="Width"
                                                             From="300"
                                                             To="0"
                                                             Duration="00:00:00.25" />
                                            <ObjectAnimationUsingKeyFrames Duration="00:00:00.25"
                                                                           Storyboard.TargetName="CloseCall"
                                                                           Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="00:00:00">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Collapsed</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Duration="00:00:00.25"
                                                                           Storyboard.TargetName="OpenCall"
                                                                           Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="00:00:00">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </ei:ControlStoryboardAction.Storyboard>
                                </ei:ControlStoryboardAction>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Button>                   
                </Grid>
                <Border Grid.Column="1"
                        x:Name="TabContent">
                    <control:ScalePanel x:Name="TabContentScalePanel"
                                        Width="300">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="60" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>
                            <Border Grid.RowSpan="2">
                                <Border.Background>
                                    <RadialGradientBrush Center="0.5,0"
                                                         GradientOrigin="0.5,0"
                                                         RadiusX="0.6"
                                                         RadiusY="0.2">
                                        <GradientStop Color="#FFFFCA3C"
                                                      Offset="1" />
                                        <GradientStop Color="#FFFFFFD5" />
                                    </RadialGradientBrush>
                                </Border.Background>
                            </Border>
                            <Border Grid.RowSpan="2">
                                <Border.Background>
                                    <RadialGradientBrush Center="0.5,1"
                                                         GradientOrigin="1,0"
                                                         RadiusX="1"
                                                         RadiusY="0.8"
                                                         Opacity="0.25">
                                        <GradientStop Color="#FFFFCA3C"
                                                      Offset="1" />
                                        <GradientStop Color="#FFFFFFD5"
                                                      Offset="1" />
                                    </RadialGradientBrush>
                                </Border.Background>
                            </Border>
                            <Border Grid.Row="0"
                                    VerticalAlignment="Top"
                                    HorizontalAlignment="Stretch"
                                    Margin="0,5,10,15">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*" />
                                    </Grid.ColumnDefinitions>
                                    <TextBlock Grid.Column="0"
                                               HorizontalAlignment="Center"
                                               Text="Common Part" />
                                </Grid>
                            </Border>
                            <Border Grid.Row="1"
                                    VerticalAlignment="Stretch">
                                <Grid>
                                    <ContentPresenter x:Name="ContentRight"
                                                      HorizontalAlignment="Stretch"
                                                      VerticalAlignment="Stretch"></ContentPresenter>
                                </Grid>
                            </Border>
                        </Grid>
                    </control:ScalePanel>
                </Border>
                <Grid Grid.Column="2">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <ItemsPresenter Grid.Row="0" />
                </Grid>
            </Grid>
        </ControlTemplate> 
 
In Above ControlTemplate creates Polygon button to show/hide panel (side bar) and style for TabControl background to set GradientColor.
Created one Trigger for Side bar control and storyboard for animation.
on button click, it executes trigger to show/hide side bar with doubleAnimation.
 
<DoubleAnimation Storyboard.TargetName="TabContentScalePanel"
       Storyboard.TargetProperty="Width"
       From="300"
       To="0"
       Duration="00:00:00.25" />
This code describes to animate scalepanel and set width from 300 to 0.
 
Step 5 : Drag & Drop TabControl into your Page.
 <sdk:TabControl x:Name="MenuItemsTabControl"
                    TabStripPlacement="Right"
                    UseLayoutRounding="True"
                    HorizontalContentAlignment="Stretch"
                    VerticalContentAlignment="Top"
                    Padding="0"
                    Margin="0">
        <sdk:TabControl.Resources>
            <Style TargetType="sdk:TabItem">
                <Setter Property="Template"
                        Value="{StaticResource RightMenuTabItem}" />
            </Style>
            <Style TargetType="sdk:TabControl">
                <Setter Property="Template"
                        Value="{StaticResource RightMenuTabControl}" />
            </Style>
        </sdk:TabControl.Resources>
    </sdk:TabControl> 

In
Above code, applying style and Template to TabControl and TabItems.

Step 6: Switch to ViewModel, Create HeaderViewModel.
 
For notify property on change, download Silverlight.Extensions.dll from http://www.Silverligh.net ,and add reference into your project.
It will add VieModelBase class which inherits from INotifyPropertyChanged for propertyChangeNotification.
VieModelBase class adds methods for RegisterPropertyChangeCallback and process child element.

HeaderViewModel.cs 
  public class HeaderViewModel : ViewModelBase
    {
        public String Header { get; set; }

        public HeaderViewModel()
        { }
        public HeaderViewModel(String header)
        {
            Header = header;
        }
    } 
In above class created Header property to set header on TabItems.
Setp 7 : Create ViewModels for Each TabItems.
DepartmentViewModel.cs 
 public class DepartmentViewModel : HeaderViewModel
    {
        protected Department Department { get;  set; }

        public string DepartmentName
        {
            get { return Department.DepartmentName; }
            set
            {
                Department.DepartmentName = value;
                RaisePropertyChanged(() => DepartmentName);
            }
        }
        public string DepartmentCode
        {
            get { return Department.DepartmentCode; }
            set
            {
                Department.DepartmentCode = value;
                RaisePropertyChanged(() => DepartmentCode);
            }
        }

        public DepartmentViewModel()
            : base("Department")
        {
            Department = new Department() { DepartmentName = "Production", DepartmentCode = "123" };
        }
    } 
In above code, created wrapper for Department Class which Defines  properties from department class and raise property that notify to view on change.
Same way create ViewModel for Employee and Product class to bind properties to view.
 
Step 8 : Create TabPropertiesViewModel which holds all viewmodels added into Items collection.
TabPropertiesViewModel.cs 
 public class TabPropertiesViewModel : ViewModelBase
    {
        private DepartmentViewModel _departmentViewModel;
        public DepartmentViewModel DepartmentViewModel
        {
            get { return _departmentViewModel; }
            set
            {
                _departmentViewModel = value;
                RaisePropertyChanged(() => DepartmentViewModel);
            }
        }
        private EmployeeViewModel _employeeViewModel;

        public EmployeeViewModel EmployeeViewModel
        {
            get { return _employeeViewModel; }
            set
            {
                _employeeViewModel = value;
                RaisePropertyChanged(() => EmployeeViewModel);
            }
        }

        private ProductViewModel _productViewModel;

        public ProductViewModel ProductViewModel
        {
            get { return _productViewModel; }
            set
            {
                _productViewModel = value;
                RaisePropertyChanged(() => ProductViewModel);
            }
        }

        public ObservableCollection<HeaderViewModel> Items { get; set; }

        public TabPropertiesViewModel()
        {
            DepartmentViewModel = ProcessChild(new DepartmentViewModel());
            EmployeeViewModel = ProcessChild(new EmployeeViewModel());
            ProductViewModel = ProcessChild(new ProductViewModel());

            Items = new ObservableCollection<HeaderViewModel>{ 
                DepartmentViewModel,
                EmployeeViewModel,
                ProductViewModel,            
            };
        }
    }
Created Properties for each view model.
I have crated collection of HeaderViewModel because it is base class for all view model.
In constructor of class, create instance of each view model and added  into item collection. 
 
Step 9 : Crate Views for Viewmodel.
DepartmentView.xaml

EmployeeView.xaml

ProductView.xaml
In above three view bind view model properties to view.
TabPropertiesView.xaml
 <Grid x:Name="LayoutRoot"
          Background="White">
        <controls:SideMenuControl ItemsSource="{Binding Items}" />
    </Grid>

Place SideMenuControl.xaml  into UserControl by adding reference (i.e. xmlns:controls="clr-namespace:SideMenuTabControl.Controls") and bind itemsSource from ViewModel. 
 
Step 10 : Binding TabItes to TabControl into SideMenuControl.
SideMenuControl.xaml.cs 
  public partial class SideMenuControl : UserControl
    {
        #region ItemsSourceProperty
        public IEnumerable<HeaderViewModel> ItemsSource
        {
            get { return (IEnumerable<HeaderViewModel>)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }

        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register("ItemsSource"
            typeof(IEnumerable<HeaderViewModel>), 
            typeof(SideMenuControl),
            new PropertyMetadata(null, new PropertyChangedCallback(ItemsSourceChanged)));

        public static void ItemsSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            SideMenuControl obj = sender as SideMenuControl;
            if (obj != null)
            {
                obj.OnItemsSourceChanged(e);
            }
        }

        private void OnItemsSourceChanged(DependencyPropertyChangedEventArgs e)
        {
            MenuItemsTabControl.ItemsSource = BuildItemsSource(ItemsSource);
            MenuItemsTabControl.SelectedIndex = 0;
        }

        private IEnumerable BuildItemsSource(IEnumerable<HeaderViewModel> ItemsSource)
        {
            Dictionary<Type, UserControl> views = new Dictionary<Type, UserControl>() { 
                { typeof(EmployeeViewModel), new EmployeeView() },
                { typeof(DepartmentViewModel), new DepartmentView() },
                { typeof(ProductViewModel), new ProductView() }
            };

            foreach (var item in ItemsSource)
            {
                TabItem tabItem = new TabItem();
                if (views.ContainsKey(item.GetType()))
                {
                    tabItem.Header = item.Header;
                    UserControl view = views[item.GetType()];
                    view.DataContext = item;
                    tabItem.Content = view;
                }
                yield return tabItem;
            }
        }
        #endregion
        public SideMenuControl()
        {
            InitializeComponent();
            MenuItemsTabControl.SizeChanged += new SizeChangedEventHandler(MenuItemsTabControl_SizeChanged);          
        }
        void MenuItemsTabControl_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (ItemsSource == null)
                return;
            Int32 itemCount = ItemsSource.Count();
            if (itemCount >= 2)
            {
                Int32 selectedIndex = MenuItemsTabControl.SelectedIndex;
                MenuItemsTabControl.SelectedIndex = itemCount - 1;
                MenuItemsTabControl.SelectedIndex = selectedIndex;
            }
        }
    } 
 
In above code I have created DepenencyProperty fot itemsSource which type is Collection of IEnumerable. 
  • IEnumerable 
    .NET framework provides IEnumerable and IEnumerator interfaces to implement collection like behavior to user defined classes. A developer can implement these interfaces to provide collection like behavior to their classes.
    The IEnumerable interface contains an abstract member function called GetEnumerator() and return an interface IEnumerator on any success call. This IEnumerator interface will allow us to iterate through any custom collection. 
    The IEnumerable<T> interface is a generic interface that provides an abstraction for looping over elements.
    I have written BuildItemsSource method to return collection of viewmodels and its return type is IEnumerable.
I have used Yield keyword which return enumerator object.

  • Yield
    The yield keyword is used in an iterator block to provide a value to the enumerator object or to signal the end of the iteration. When used the expression is evaluated and returned as a value to the enumerator object.
    The yield keyword signals to the compiler that the method in which it appears is an iterator block. The compiler generates a class to implement the behavior that is expressed in the iterator block. In the iterator block, the yield keyword is used together with the return keyword to provide a value to the enumerator object. This is the value that is returned.
    A yield statement cannot appear in an anonymous method.
I have write SizeChange Event Handler for MenuItemsTabControl which provides user to maintain selected index of TabItems when user show/hide sidebar.

You can download Source from : TabControlWithSideBar