TabStrip placement and verticaltext

There are couple of ways to display Vertical text in TabItem

Here are 2 ways

1. Get the code for the VerticalTextblock from here and use it like this. I could not get the Binding to work but hard coding Text works

 <my:TabControl TabStripPlacement=”Left”>
             <my:TabItem Header=”Tab1″>
                <TextBlock Text=”Some Text in Tab1″ />
                 <my:TabItem.HeaderTemplate>
                    <DataTemplate>
                       <local:VerticalTextBlock Text=”Tab1″ />
                    </DataTemplate>
                </my:TabItem.HeaderTemplate>
            </my:TabItem>
            <my:TabItem Header=”tab2″>
                <TextBlock Text=”Some Text in Tab2″ />
                 <my:TabItem.HeaderTemplate>
                    <DataTemplate>
                      <local:VerticalTextBlock Text=”Tab2″ />
                    </DataTemplate>
                </my:TabItem.HeaderTemplate>
            </my:TabItem>
        </my:TabControl>

2. Use ItemsControl and set the ItemsSource to the Text we want to display

<my:TabControl TabStripPlacement=”Left”>
            <my:TabItem Header=”Tab1″>
                <TextBlock Text=”Some Text in Tab1″ />
                <my:TabItem.HeaderTemplate>
                    <DataTemplate>
                        <ItemsControl HorizontalAlignment=”Center”
                                      HorizontalContentAlignment=”Center”
                                      ItemsSource=”Tab1″></ItemsControl>
                    </DataTemplate>
                </my:TabItem.HeaderTemplate>
            </my:TabItem>
  </my:TabControl>

update:Added screenshot

Advertisements

Looking for a job

My current contract  job where I do c#, asp.net, wcf, sql server is ending. if you, or someone you know is looking for a consultant with any or all of c#, WPF, WCF, Silverlight, asp.net, sqlserver, linq etc in and around Dallas, TX, please drop a line or send me an email, I can send my detailed resume and contact information for your consideration

Dynamic Styles – part 2

In the last post we saw we could change the skin of the application without reloading the app. what is missing is when the user opens the app the next time, it doesnt remember the last theme selected. To start the app with the last selected theme when the user runs the app again is quite easy

We need to make the changes only in couple of places.

In Page.xaml.cs, before we clear the ApplciationSettings, we get the theme we stored, if it is there and after we load all our themes we default to the one we got from ApplicationSettings. When the user changes the Theme we save it in the ThemeChanged eventhandler.

The modified version of the code in Page.xaml.cs is below

 public Page()
        {
            string currentTheme = “DefaultTheme”;
           
            if (IsolatedStorageSettings.ApplicationSettings.Contains(“CurrentTheme”))
                currentTheme = IsolatedStorageSettings.ApplicationSettings[“CurrentTheme”] as string;

            IsolatedStorageSettings.ApplicationSettings.Clear();
            IsolatedStorageSettings.ApplicationSettings.Add(“CurrentTheme”, currentTheme);

            GetThemes(“Default”);
            GetThemes(“Red”);
            GetThemes(“Flat”);
            InitializeComponent();
            LayoutRoot.Background = App.Current.Resources[“BkgBrush”] as SolidColorBrush;

            ThemeSelection ts = new ThemeSelection(currentTheme);
            cc2.Content = ts;
            ts.ThemeChanged += new ThemeSelection.ThemeChangedEventHandler(ts_ThemeChanged);
            MainContent mc = new MainContent();
            cc1.Content = mc;
                    
        }

 void ts_ThemeChanged(object sender, ThemeChangedEventArgs e)
        {           
            ThemeSelection ts = new ThemeSelection(e.Theme);
            IsolatedStorageSettings.ApplicationSettings[“CurrentTheme”] = e.Theme;
            cc2.Content = ts;
            MainContent mc = new MainContent();
            cc1.Content = mc;
            ts.ThemeChanged += new ThemeSelection.ThemeChangedEventHandler(ts_ThemeChanged);
            LayoutRoot.Background = App.Current.Resources[“BkgBrush”] as SolidColorBrush;
        }

 

With these changes in place, when the user runs the application, it shows up with the theme where he left the last time

Dynamic Styles

In this post, I will show my attempt to change the Theme of SL application without reloading the app.
you can see a demo here . There are 3 main steps

1. Isolate all the styles into individual files .xaml or xml
2. load all the resources and save them
3. clear the Application Resources before the content is initialized

I modified the Red and Flat styles from Corrina http://blogs.msdn.com/corrinab/archive/2008/06/16/8602865.aspx) to include namespaces on all of them

It allows switching between 3 themes.

Here are the screenshots


The main(page.xaml) content is as follows

<Grid x:Name=”LayoutRoot” >     
        <ContentControl x:Name=”cc1″ Width=”700″ Height=”500″/>
        <ContentControl x:Name=”cc2″
                        Width=”300″
                        Height=”50″
                        HorizontalAlignment=”Right”
                        VerticalAlignment=”Top” />
    </Grid>

cc2 is the ContentControl into which usercontrol(ThemeSelection) will be loaded. cc1 is the ContentControl into which the actual content will be loaded

The codebehind(page.xaml.cs) constructor has the following

 public Page()
        {
            IsolatedStorageSettings.ApplicationSettings.Clear();
         
            GetThemes(“Default”);
            GetThemes(“Red”);
            GetThemes(“Flat”);
            InitializeComponent();
            LayoutRoot.Background = App.Current.Resources[“BkgBrush”] as SolidColorBrush;
           
            ThemeSelection ts = new ThemeSelection(“DefaultTheme”);
            cc2.Content = ts;
            ts.ThemeChanged += new ThemeSelection.ThemeChangedEventHandler(ts_ThemeChanged);
            MainContent mc = new MainContent();
            cc1.Content = mc;
                    
        }
what we are doing is clearing the ApplciationSettings, getting styles for different themes using StreamResourceInfo and populating a list which inturn is added to ApplicationSettings. When the theme is changed the Usercontrol(where we make the theme selection), raises an event which is handled  like this

 void ts_ThemeChanged(object sender, ThemeChangedEventArgs e)
        {           
            ThemeSelection ts = new ThemeSelection(e.Theme);
            cc2.Content = ts;
            MainContent mc = new MainContent();
            cc1.Content = mc;
            ts.ThemeChanged += new ThemeSelection.ThemeChangedEventHandler(ts_ThemeChanged);
            LayoutRoot.Background = App.Current.Resources[“BkgBrush”] as SolidColorBrush;
        }
The UserControl(MainContent.xaml) has the applciation specific logic, nothing special w.r.t themes, except for the fact that the current selection is maintained in the listbox by saving the selected item in IsolatedStorageSettings.ApplicationSettings.

ThemeSelection.xaml is the UserControl where we make the ThemeSelection which has logic to raise the event, when the theme changes we reload. The contentControls clear the App.Resources and load the styles from IsolatedStorageSettings.ApplicationSettings
  private void SetTheme(string s)
        {
            App.Current.Resources.Clear();
            List<Theme> themeSettings = new List<Theme>();          
            themeSettings = IsolatedStorageSettings.ApplicationSettings[s] as List<Theme>;
          
            foreach (Theme t in themeSettings)
                App.Current.Resources.Add(t.Key, XamlReader.Load(t.Value));  
        }

It doesnt have any optimizations or error checking, so the initial load(bit slow) and time for changing themes could be reduced by some variations

you can download the source here

please leave a comment if you have any variations that you come up with.

VerticalAlignment of header in DataGrid

If we want to align the content of the header vertically(Bottom) in datagrid, found that we need to change the style. I thought there would be an easier way, but could not find one.

 

xmlns:my1=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data”

Here is the style, changes made to the default style in Bold

<Style TargetType=”my1:DataGridColumnHeader”>
<Setter Property=”SeparatorBrush”>
    <Setter.Value>
        <SolidColorBrush Color=”#FFA4A4A4″ />
    </Setter.Value>
</Setter>
<Setter Property=”SeparatorVisibility”
        Value=”Visible” />
<Setter Property=”Template”>
    <Setter.Value>
        <ControlTemplate TargetType=”my1:DataGridColumnHeader”>
            <Grid Name=”RootElement” >
                <Grid.Background>
                    <LinearGradientBrush StartPoint=”0.276463,-0.00385181″
                                         EndPoint=”0.276463,0.71″>
                        <GradientStop Color=”#FFF9FAFA”
                                      Offset=”0″ />
                        <GradientStop Name=”StopColor2″
                                      Color=”#FFEDF1F4″
                                      Offset=”0.37259″ />
                        <GradientStop Name=”StopColor3″
                                      Color=”#FFE2E8EF”
                                      Offset=”0.372881″ />
                        <GradientStop Name=”StopColor4″
                                      Color=”#FFC3C9CD”
                                      Offset=”1″ />
                    </LinearGradientBrush>
                </Grid.Background>

                <Grid.Resources>
                    <Storyboard x:Key=”Normal State”>
                        <ColorAnimation Storyboard.TargetName=”StopColor2″
                                        Storyboard.TargetProperty=”(Color)”
                                        Duration=”00:00:0.3″
                                        To=”#FFEDF1F4″ />
                        <ColorAnimation Storyboard.TargetName=”StopColor3″
                                        Storyboard.TargetProperty=”(Color)”
                                        Duration=”00:00:0.3″
                                        To=”#FFE2E8EF” />
                        <ColorAnimation Storyboard.TargetName=”StopColor4″
                                        Storyboard.TargetProperty=”(Color)”
                                        Duration=”00:00:0.3″
                                        To=”#FFC3C9CD” />
                    </Storyboard>
                    <Storyboard x:Key=”MouseOver State”>
                        <ColorAnimation Storyboard.TargetName=”StopColor2″
                                        Storyboard.TargetProperty=”(Color)”
                                        Duration=”00:00:0.3″
                                        To=”#FFE6EFF7″ />
                        <ColorAnimation Storyboard.TargetName=”StopColor3″
                                        Storyboard.TargetProperty=”(Color)”
                                        Duration=”00:00:0.3″
                                        To=”#FFD3E4F5″ />
                        <ColorAnimation Storyboard.TargetName=”StopColor4″
                                        Storyboard.TargetProperty=”(Color)”
                                        Duration=”00:00:0.3″
                                        To=”#FF87A5BA” />
                    </Storyboard>
                    <Storyboard x:Key=”Unsorted State”>
                        <DoubleAnimation Storyboard.TargetName=”SortIconElement”
                                         Storyboard.TargetProperty=”Opacity”
                                         Duration=”00:00:0.3″
                                         To=”0.0″ />
                        <DoubleAnimation Storyboard.TargetName=”SortIconTransform”
                                         Storyboard.TargetProperty=”ScaleY”
                                         BeginTime=”00:00:0.3″
                                         Duration=”00:00:0.0″
                                         To=”1″ />
                    </Storyboard>
                    <Storyboard x:Key=”SortedAscending State”>
                        <DoubleAnimation Storyboard.TargetName=”SortIconElement”
                                         Storyboard.TargetProperty=”Opacity”
                                         Duration=”00:00:0.3″
                                         To=”1.0″ />
                        <DoubleAnimation Storyboard.TargetName=”SortIconTransform”
                                         Storyboard.TargetProperty=”ScaleY”
                                         Duration=”00:00:0.3″
                                         To=”-1″ />
                    </Storyboard>
                    <Storyboard x:Key=”SortedDescending State”>
                        <DoubleAnimation Storyboard.TargetName=”SortIconElement”
                                         Storyboard.TargetProperty=”Opacity”
                                         Duration=”00:00:0.3″
                                         To=”1.0″ />
                        <DoubleAnimation Storyboard.TargetName=”SortIconTransform”
                                         Storyboard.TargetProperty=”ScaleY”
                                         Duration=”00:00:0.3″
                                         To=”1″ />
                    </Storyboard>
                </Grid.Resources>

                <Grid.RowDefinitions>
                    <RowDefinition Height=”*” />
                    <RowDefinition Height=”*” />
                    <RowDefinition Height=”Auto” />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width=”*” />
                    <ColumnDefinition Width=”Auto” />
                    <ColumnDefinition Width=”Auto” />
                </Grid.ColumnDefinitions>

                <Rectangle Stretch=”Fill”
                           StrokeThickness=”2″
                           Stroke=”#FFFFFFFF”
                           Grid.ColumnSpan=”2″
                           Grid.RowSpan=”2″ />
                <Rectangle Grid.Row=”2″
                           Grid.ColumnSpan=”3″
                           Height=”1″
                           HorizontalAlignment=”Stretch”
                           Fill=”#FFA4A4A4″ />
                <Rectangle Grid.RowSpan=”2″
                           Grid.Column=”2″
                           Width=”1″
                           VerticalAlignment=”Stretch”
                           Fill=”{TemplateBinding SeparatorBrush}”
                           Visibility=”{TemplateBinding SeparatorVisibility}” />
                <!– TODO: Put this back when SL gets ViewBox; Currently this path kills autosizing
            <Path Margin=”1,1,1,0″ Stretch=”Fill” Grid.ColumnSpan=”2″ Data=”F1 M 547.239,124.863L 430.795,124.863L 430.795,135.106C 447.845,138.848 467.753,140.997 489.017,140.997C 510.281,140.997 530.188,138.848 547.239,135.106L 547.239,124.863 Z “>
                <Path.Fill>
                    <LinearGradientBrush StartPoint=”0.5125,-0.0864589″ EndPoint=”0.5125,1.00202″>
                        <GradientStop Color=”#B3FFFFFF” Offset=”0″/>
                        <GradientStop Color=”#3CFFFFFF” Offset=”1″/>
                    </LinearGradientBrush>
                </Path.Fill>
            </Path>
            –>

                <ContentPresenter Margin=”3,0,3,0″ Grid.RowSpan=”3″ 
                                           Content=”{TemplateBinding Content}”
                                           VerticalAlignment=”Bottom” />
                <Path Name=”SortIconElement”
                      Margin=”3,0,3,0″
                      Opacity=”0″
                      Grid.Column=”1″ Grid.Row=”1″
                      Stretch=”Uniform”
                      Width=”8″
                      Data=”F1 M -5.215,0.0L 5.215,0.0L 0,6.099L -5.215,0.0 Z “>
                    <Path.Fill>
                        <SolidColorBrush Color=”#FF313131″ />
                    </Path.Fill>
                    <Path.RenderTransform>
                        <ScaleTransform Name=”SortIconTransform”
                                        CenterX=”4″
                                        CenterY=”2.5″
                                        ScaleX=”1″
                                        ScaleY=”1″ />
                    </Path.RenderTransform>
                </Path>
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>
</Style>

Customizing ListBoxItem template in ListBox

ItemContainerStyle is the style that is applied to the dataitems.  In the figure below we see the default style that comes with the listbox on the left and style that is customized on the right.

 

Here are the steps

1. Get the default style for the ListBoxItem from generic.xaml using reflector or from the sdk

2. Remove all the UI/Shape elements except the ContentPresenter and the storyboard(s) where they are referenced.

3.change the contents of the Grid in the template to the following

<Grid Margin=”5″
      Background=”{TemplateBinding Background}”>  
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width=”20″ />
        <ColumnDefinition Width=”*” />
    </Grid.ColumnDefinitions>

    <Ellipse  Width=”20″
              Height=”20″
              Grid.Column=”0″
              Stroke=”Black”
              IsHitTestVisible=”False”>
        <Ellipse.Fill>
            <SolidColorBrush x:Name=”SelectedVisual”
                             Color=”Beige” />
        </Ellipse.Fill>
    </Ellipse>
    <Border Margin=”2″
            Grid.Column=”1″
            x:Name=”border”
            CornerRadius=”5″
            BorderThickness=”1″>
        <Border.BorderBrush>
            <SolidColorBrush Color=”Transparent”
                             x:Name=”borderBrush”></SolidColorBrush>
        </Border.BorderBrush>
        <ContentPresenter Margin=”2″
                          Content=”{TemplateBinding Content}”
                          ContentTemplate=”{TemplateBinding ContentTemplate}”
                          HorizontalAlignment=”Left”
                          HorizontalContentAlignment=”{TemplateBinding HorizontalContentAlignment}”
                          Padding=”{TemplateBinding Padding}”
                          TextAlignment=”{TemplateBinding TextAlignment}”
                          TextDecorations=”{TemplateBinding TextDecorations}”
                          TextWrapping=”{TemplateBinding TextWrapping}”
                          VerticalContentAlignment=”{TemplateBinding VerticalContentAlignment}” />
    </Border>
</Grid>

4 Add some storyboards to change the color of the BorderBrush and the ellipse and we are done

<vsm:VisualStateManager.VisualStateGroups>
    <vsm:VisualStateGroup x:Name=”CommonStates”>
        <vsm:VisualState x:Name=”Normal” />
        <vsm:VisualState x:Name=”MouseOver”>
          <Storyboard>
                <ColorAnimation Storyboard.TargetName=”SelectedVisual”
                                Storyboard.TargetProperty=”Color”
                                To=”Yellow” />
            </Storyboard>
        </vsm:VisualState>
    </vsm:VisualStateGroup>
    <vsm:VisualStateGroup x:Name=”SelectionStates”>
        <vsm:VisualState x:Name=”Unselected”>
            <Storyboard>
                <ColorAnimation Storyboard.TargetName=”SelectedVisual”
                                Storyboard.TargetProperty=”Color”
                                To=”Beige” />
            </Storyboard>
        </vsm:VisualState>
        <vsm:VisualState x:Name=”Selected”>
            <Storyboard>
                <ColorAnimation Storyboard.TargetName=”SelectedVisual”
                                Storyboard.TargetProperty=”Color”
                                To=”Green” />
            </Storyboard>
        </vsm:VisualState>
    </vsm:VisualStateGroup>
    <vsm:VisualStateGroup x:Name=”FocusStates”>
        <vsm:VisualState x:Name=”Focused”>
            <Storyboard>
                <ColorAnimation Storyboard.TargetName=”borderBrush”
                                Storyboard.TargetProperty=”Color”
                                To=”Black” />
            </Storyboard>
        </vsm:VisualState>
        <vsm:VisualState x:Name=”Unfocused”>
            <Storyboard>
                <Storyboard>
                    <ColorAnimation Storyboard.TargetName=”borderBrush”
                                    Storyboard.TargetProperty=”Color”
                                    To=”Transparent” />
                </Storyboard>
            </Storyboard>
        </vsm:VisualState>
    </vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>

you can download the source here

Communication between UserControls

There  are different ways to communicate between usercontrols. Here is a sample of that using events. Basically an event is raised when something happens in one Usercontrol an event is raised and Page which  contains the UserControl subscribes to the event and passes the relevant details it to a different UserControl

you can download the sample here