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 😀

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

[sourcecode language=”XML”]
<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>
[/sourcecode]

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)

[sourcecode language=”csharp”]

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));
}
}
}
}

[/sourcecode]

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

[sourcecode language=”XML”]
<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>
[/sourcecode]

  15 Responses to “Example Metro app /WinRT: Homemade Chart and DatePicker for Metro Apps”

  1. […] I offer the following simplifications to get us started…”Apps & Code to Look AtExample Metro app /WinRT: Homemade Chart and DatePicker for Metro Apps (Iris Classon)“Iris Classon on Twitter 18 July: “I’ll make my own darn charts, […]

  2. 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. […] Example Metro app /WinRT: Homemade Chart and DatePicker for Metro Apps (Iris Classon) […]

  4. 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. :-)

  5. 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

  6. I think the Piechart Code is mine right :)

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

  8. […] Example Metro app /WinRT: Homemade Chart and DatePicker for Metro Apps […]

  9. 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.

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

  11. 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 😛 I don’t have one to test though..

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

What is 12 + 3 ?
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) :-)