Click here to Skip to main content
Licence CPOL
First Posted 22 Dec 2011
Views 3,784
Downloads 384
Bookmarked 6 times

Customize Tab Control in Silverlight (create tab control with side bar)

By | 22 Dec 2011 | Article
Createing TabControl with SideMenu and SideBar

Introduction

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.

Background

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.

Using the 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.

http://msdn.microsoft.com/en-us/library/cc221408%28v=vs.95%29.aspx

 

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   

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.measureoverride%28v=vs.95%29.aspx

  • 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

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.arrangeoverride%28v=vs.95%29.aspx 

 

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 : Create 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. 

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Hiren Khirsaria

Software Developer (Senior)
Priya Softweb Solutions
India India

Member

has 3 + Total Experience in Microsoft.Net Environment.
 
2 + year Excperience in .Net Development with C# and SQL Server 2005/2008.
 
1 + Experience in WPF/Silverlight.
 
Current area of Development in Silverlight/ WPF and Windows Phone 7 Application.
 
Follow me on : http://hirenkhirsaria.blogspot.com/

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionScreenshot Pinmemberjeffb426:19 22 Dec '11  
AnswerRe: Screenshot Pinmemberkapil bhavsar18:43 26 Dec '11  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 23 Dec 2011
Article Copyright 2011 by Hiren Khirsaria
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid