Jul 192012
 
 July 19, 2012  Posted by at 1:57 pm WinRT  Add comments

Iris Classon on Twitter 18 July:

I’ll make my own darn charts, and they will be FREE. HA! I’ll use rectangles for bar-series :D

Here is how the charts turned out (I’m not ready to share this code yet, but I will once I clean it up a little!) – The barchart is by be, and the Piechart by another developer, I just did the legends. I’ll ask him if he is fine with sharing, and I’ll post the code here.

Homemade XAML/Metro App charts. Barchart and legends by me, Pichart by another dev.

a Telerik's charts for windows 8 sample I made earlier this week, beta is out- you should try!

And so I did. Out of pure frustration I decided to remove third party libraries from my Metro app to make it model-skinny,- and to get total control. And talking about controls, I made some of them- and I don’t mind sharing :) – starting with my datepicker. A simple control that anybody can throw together, but it is all those extra hours here and there that breaks deadlines, and that is why I at least like getting some help. Maybe I can be the one to help this time? Anyways, here you go – use it as you please. DatePicker a lá Iris.

simple datepicker for Metro apps by me

You can download the sample of the datepicker here

The View

<Page
    x:Class="DIYDatePicker.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    mc:Ignorable="d">
    <Page.Resources>
        <DataTemplate x:Key="DateTemplate">
            <Border Background="#FF0043A2" Height="80" Width="80">
                <StackPanel HorizontalAlignment="Left" VerticalAlignment="Center">
                    <TextBlock Text="{Binding}" Foreground="White" FontWeight="Light" FontSize="24" HorizontalAlignment="Left" Margin="9,2,0,0" VerticalAlignment="Center"/>
                </StackPanel>
            </Border>
        </DataTemplate>
    </Page.Resources>
    
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Border Background="White" Padding="2" Width="350" Height="100" BorderBrush="White" BorderThickness="10">
            <StackPanel Orientation="Horizontal">
                <ComboBox ScrollViewer.VerticalScrollBarVisibility="Hidden" ItemTemplate="{StaticResource DateTemplate}" ItemsSource="{Binding Date.Year}"  Width="100" MaxDropDownHeight="1" SelectedItem="{Binding Year, Mode=TwoWay}" Style="{StaticResource ComboBoxStyle1}"/>
                <ComboBox ScrollViewer.VerticalScrollBarVisibility="Hidden" ItemTemplate="{StaticResource DateTemplate}" ItemsSource="{Binding Date.Month}"  Width="100" MaxDropDownHeight="1" SelectedItem="{Binding Month, Mode=TwoWay}" Style="{StaticResource ComboBoxStyle1}"/>
                <ComboBox ScrollViewer.VerticalScrollBarVisibility="Hidden" ItemTemplate="{StaticResource DateTemplate}" ItemsSource="{Binding Date.Day}"  Width="100" MaxDropDownHeight="1" SelectedItem="{Binding Day, Mode=TwoWay}" Style="{StaticResource ComboBoxStyle1}"/>
            </StackPanel>
        </Border>
    </Grid>
</Page>

Code (You should of course not have everything in one class/file, it’s just to keep it simple I’m doing this in my examples)


using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace DIYDatePicker
{
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
private int _day;
private int _month;
private int _year;
private Date _date = new Date();

public int Day
{
get { return _day; }
set
{
if (_day == value) return;
_day = value;
NotifyPropertyChanged("Day");
}
}

public int Month
{
get { return _month; }
set
{
if (_month == value) return;
_month = value;
_date.Day =
new ObservableCollection((Enumerable.Range(1, DateTime.DaysInMonth(DateTime.Now.Year, _month))));
NotifyPropertyChanged("Month");
}
}

public int Year
{
get { return _year; }
set
{
if (_year == value) return;
_year = value;
_date.Day = new ObservableCollection((Enumerable.Range(1, DateTime.DaysInMonth(_year, _month))));
NotifyPropertyChanged("Year");
}
}

public Date Date
{
get { return _date; }
}

private int GetDaysInMonth(int year, int month)
{
return DateTime.DaysInMonth(year, month);
}

public MainPage()
{
this.InitializeComponent();
SetTodaysDate();
SetDataSource();
}

private void SetTodaysDate()
{
Day = DateTime.Now.Day;
Month = DateTime.Now.Month;
Year = DateTime.Now.Year;
}

private void SetDataSource()
{
int year = DateTime.Now.Year - 10;
_date.Day = new ObservableCollection(Enumerable.Range(1, GetDaysInMonth(Year, 1)));
_date.Month = new ObservableCollection(Enumerable.Range(1, 12));
_date.Year = new ObservableCollection(Enumerable.Range(year, 20));
}

protected override void OnNavigatedTo(NavigationEventArgs e){}

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

public class Date : INotifyPropertyChanged
{
private ObservableCollection _day;
private ObservableCollection _month;
private ObservableCollection _year;

public ObservableCollectionDay
{
get { return _day; }
set
{
if (_day == value) return;
_day = value;
NotifyPropertyChanged("Day");
}
}

public ObservableCollectionMonth
{
get { return _month; }
set
{
if (_month == value) return;
_month = value;
NotifyPropertyChanged("Month");
}
}

public ObservableCollectionYear
{
get { return _year; }
set
{
if (_year == value) return;
_year = value;
NotifyPropertyChanged("Year");
}
}

public event PropertyChangedEventHandler PropertyChanged;

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

You will have to re-design the comboboxes, add this as an resource.

<Style x:Key="ComboBoxStyle1" TargetType="ComboBox">
        <Setter Property="Padding" Value="0"/>
        <Setter Property="Foreground" Value="{StaticResource ComboBoxForegroundThemeBrush}"/>
        <Setter Property="Background" Value="{StaticResource ComboBoxBackgroundThemeBrush}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ComboBoxBorderThemeBrush}"/>
        <Setter Property="BorderThickness" Value="{StaticResource ComboBoxBorderThemeThickness}"/>
        <Setter Property="TabNavigation" Value="Once"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/>
        <Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto"/>
        <Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True"/>
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
        <Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <CarouselPanel/>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ComboBox">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="10"/>
                        </Grid.ColumnDefinitions>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="PointerOver">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxPointerOverBackgroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxPointerOverBorderThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="Highlight">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxSelectedPointerOverBackgroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxPressedBackgroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxPressedBorderThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxPressedForegroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PressedBackground"/>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DropDownGlyph">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxArrowPressedForegroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxDisabledBackgroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxDisabledBorderThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxDisabledForegroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DropDownGlyph">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxArrowDisabledForegroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="FocusStates">
                                <VisualState x:Name="Focused">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HighlightBackground"/>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Highlight"/>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxFocusedForegroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="FocusedPressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxPressedForegroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="Highlight">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ComboBoxPressedHighlightThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Unfocused"/>
                                <VisualState x:Name="PointerFocused"/>
                                <VisualState x:Name="FocusedDropDown">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="PopupBorder">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="DropDownStates">
                                <VisualState x:Name="Opened">
                                    <Storyboard>
                                        <SplitOpenThemeAnimation ClosedTargetName="ContentPresenter" ContentTranslationOffset="0" ContentTargetName="ScrollViewer" ClosedLength="{Binding TemplateSettings.DropDownClosedHeight, RelativeSource={RelativeSource Mode=TemplatedParent}}" OffsetFromCenter="{Binding TemplateSettings.DropDownOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" OpenedTargetName="PopupBorder" OpenedLength="{Binding TemplateSettings.DropDownOpenedHeight, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Closed">
                                    <Storyboard>
                                        <SplitCloseThemeAnimation ClosedTargetName="ContentPresenter" ContentTranslationOffset="40" ContentTranslationDirection="{Binding TemplateSettings.SelectedItemDirection, RelativeSource={RelativeSource Mode=TemplatedParent}}" ContentTargetName="ScrollViewer" ClosedLength="{Binding TemplateSettings.DropDownClosedHeight, RelativeSource={RelativeSource Mode=TemplatedParent}}" OffsetFromCenter="{Binding TemplateSettings.DropDownOffset, RelativeSource={RelativeSource Mode=TemplatedParent}}" OpenedTargetName="PopupBorder" OpenedLength="{Binding TemplateSettings.DropDownOpenedHeight, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2"/>
                        <Rectangle x:Name="PressedBackground" Fill="{StaticResource ComboBoxPressedHighlightThemeBrush}" Margin="{TemplateBinding BorderThickness}" Opacity="0"/>
                        <Border x:Name="HighlightBackground" BorderBrush="{StaticResource ComboBoxFocusedBorderThemeBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{StaticResource ComboBoxFocusedBackgroundThemeBrush}" Grid.ColumnSpan="2" Opacity="0"/>
                        <Rectangle x:Name="Highlight" Fill="{StaticResource ComboBoxSelectedBackgroundThemeBrush}" Margin="{TemplateBinding BorderThickness}" Opacity="0"/>
                        <ContentPresenter x:Name="ContentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        <TextBlock x:Name="DropDownGlyph" Grid.Column="1" Foreground="{StaticResource ComboBoxArrowForegroundThemeBrush}" FontWeight="Bold" FontSize="12" FontFamily="{StaticResource SymbolThemeFontFamily}" IsHitTestVisible="False" Text="" VerticalAlignment="Center" Margin="20,30,0,30"/>
                        <Popup x:Name="Popup">
                            <Border x:Name="PopupBorder" BorderBrush="{StaticResource ComboBoxPopupBorderThemeBrush}" BorderThickness="{StaticResource ComboBoxPopupBorderThemeThickness}" Background="{StaticResource ComboBoxPopupBackgroundThemeBrush}" HorizontalAlignment="Stretch">
                                <ScrollViewer x:Name="ScrollViewer" Foreground="{StaticResource ComboBoxPopupForegroundThemeBrush}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" VerticalSnapPointsType="OptionalSingle" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" VerticalSnapPointsAlignment="Near" ZoomMode="Disabled">
                                    <ItemsPresenter/>
                                </ScrollViewer>
                            </Border>
                        </Popup>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

15 comments on “Example Metro app /WinRT: Homemade Chart and DatePicker for Metro Apps

  1. Pingback: Windows 8 Developer Links – 2012-07-20Dan Rigby | Dan Rigby

  2. Simon O'Beirne on said:

    Hi Iris – those charts look pretty good. I had exactly the same thought a little while ago and I’m currently working on some pie charts myself which I’m hoping to put on github when code is a little cleaner.

    Would certainly be interested to see more on how you went about yours.

    Simon

  3. Pingback: Dew Drop – July 20, 2012 (#1,368) | Alvin Ashcraft's Morning Dew

  4. Pingback: Example Metro app /WinRT: Homemade Chart and DatePicker for Metro Apps

  5. Sebastian on said:

    Hi Iris, any news on the pie chart code? I’m currently reaching the point of just doing it myself, but if your friend would be willing to share that’d be great. :-)

  6. I’m desperately in need of a charting solution for a metro app I’m working on. Would greatly appreciate you sharing some code, no matter how rough…

    Thanks,
    Matt

  7. Mahmoud Moussa on said:

    I think the Piechart Code is mine right :)

  8. my article tools on said:

    I’m gone to say to my little brother, that he should also pay a visit this website on regular basis to get updated from newest reports.

  9. Pingback: SilverlightCream Top 5 News for August 6 - 12, 2012

  10. Hi there,

    was able to achieve something like this datepicker by using combobox and carouselpanel.
    But i can’t for the life of me, remove the visibility of the dropdownbutton. have set the DropDownGlyph’s opacity to 0 and that removed the arrow. but the button is still visible.

  11. Jawahar on said:

    Why can’t you try out new beta (it doesn’t expire) version of Syncfusion WinRT XAML controls.
    http://www.syncfusion.com/products/winrt

  12. Diogo Castro on said:

    I tried your DatePicker and it’s working wonders Iris! Thanks for sharing!

    I found what seems to be a bug though. When I run your code on the simulator, switch to touch mode and touch any of the three comboboxes, the app crashes.
    Did this happen to anyone else? Here’s what I get: https://www.dropbox.com/s/o8wcqvexzwxdvz2/datepicker_touch_error.png
    I hope this only happens on the simulator though, and not on a real touch device :P I don’t have one to test though..

  13. Farhan on said:

    Try this, https://nuget.org/packages/WinRTDatePicker

Leave a Reply

Your email address will not be published. Required fields are marked *

*

HTML tags are not allowed.

What is 6 + 6 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)