예전에 했는데도 불구하고 이번에 또 하느라 삽질을 하였다.
그래서 이렇게 포스팅 한다.
먼저 Toolkit을 설치하고 소스를 받는다.
현재 무한대로 나오는 년도를 2050년까지만 나오게 하자. 년도만 나오게도 할수 있다.
일단 복사해야할 파일은
DataSource.cs
DatePicker.cs(필요에 따라 없어도 됨)
DateTimePickerPageBase.cs
Common 폴더에 Tuple.cs
DatePickerPage.xaml
이렇게 복사한다
DatePickerPage.xaml은 UI 에 쓰이기 때문에 이름을 바꾼다.
namespace는 그냥 가만히 나두는게 좋다
만약에 저위에 처럼 년도만 보이게 하고 싶으면
DatePickerPage.xaml.cs 에서
public partial class CustomYearDatePicker : DateTimePickerPageBase
{
LoopingSelector lsMonth;
LoopingSelector lsDay;
/// <summary>
/// CustomYearDatePicker Constructor
/// </summary>
public CustomYearDatePicker()
{
InitializeComponent();
// Hook up the data sources
PrimarySelector.DataSource = new YearDataSource();
//SecondarySelector.DataSource = new MonthDataSource();
//TertiarySelector.DataSource = new DayDataSource();
//가짜 데이터 넣기
lsMonth = new LoopingSelector();
lsMonth.DataSource = new MonthDataSource();
lsDay = new LoopingSelector();
lsDay.DataSource = new MonthDataSource();
InitializeDateTimePickerPage(PrimarySelector, lsMonth, lsDay);
}
/// <summary>
/// Gets a sequence of LoopingSelector parts ordered according to culture string for date/time formatting.
/// </summary>
/// <returns>LoopingSelectors ordered thffby culture-specific priority.</returns>
protected override IEnumerable<LoopingSelector> GetSelectorsOrderedByCulturePattern()
{
return GetSelectorsOrderedByCulturePattern(
CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.ToUpperInvariant(),
new char[] { 'Y', 'M', 'D' },
//new LoopingSelector[] { PrimarySelector, SecondarySelector, TertiarySelector });
new LoopingSelector[] { PrimarySelector, lsMonth, lsDay });
}
이런식으로 바꿔준다. 가짜 데이터를 넣고 Xaml(UI)딴에서는 삭제 한다.
그리고 2050년까지만 보이게 하기 위해서
DataSource.cs를 이렇게 바꾸어 준다.
class YearDataSource : DataSource
{
protected override DateTime? GetRelativeTo(DateTime relativeDate, int delta)
{
if ((1601 == relativeDate.Year) || (3000 == relativeDate.Year))
//if ((2010 == relativeDate.Year) || (2051 == relativeDate.Year))
{
return null;
}
int nextYear = relativeDate.Year + delta;
if (nextYear < 2010)
{
nextYear = 2051 + (nextYear - 2010);
}
else if (nextYear > 2050)
{
nextYear = 2009 + (nextYear - 2050);
}
//int nextYear = relativeDate.Year + delta;
int nextDay = Math.Min(relativeDate.Day, DateTime.DaysInMonth(nextYear, relativeDate.Month));
return new DateTime(nextYear, relativeDate.Month, nextDay, relativeDate.Hour, relativeDate.Minute, relativeDate.Second);
}
}
혹시나 모르니 DatePicker.xaml을 올려둔다.
<Primitives:DateTimePickerPageBase
x:Class="Microsoft.Phone.Controls.CustomDatePicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Primitives="clr-namespace:Microsoft.Phone.Controls.Primitives;assembly=Microsoft.Phone.Controls.Toolkit"
xmlns:Controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="728" d:DesignWidth="480">
<Primitives:DateTimePickerPageBase.Resources>
<Controls:DateTimePickerResources x:Key="DateTimePickerResources"/>
<ExponentialEase x:Key="Ease" EasingMode="EaseIn"/>
</Primitives:DateTimePickerPageBase.Resources>
<Grid Background="{StaticResource PhoneChromeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisibilityStates">
<VisualState x:Name="Open">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="PlaneProjection"
Storyboard.TargetProperty="RotationX"
From="-50"
To="0"
Duration="0:0:0.2"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Closed">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="PlaneProjection"
Storyboard.TargetProperty="RotationX"
To="90"
Duration="0:0:0.2"
EasingFunction="{StaticResource Ease}"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.Projection>
<PlaneProjection x:Name="PlaneProjection"/>
</Grid.Projection>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- SystemTray placeholder -->
<Rectangle
x:Name="SystemTrayPlaceholder"
Grid.Row="0"
Height="32"/>
<!-- Title -->
<TextBlock
Grid.Row="1"
Text="{Binding DatePickerTitle, Source={StaticResource DateTimePickerResources}}"
FontFamily="{StaticResource PhoneFontFamilySemiBold}"
FontSize="{StaticResource PhoneFontSizeMedium}"
Foreground="{StaticResource PhoneForegroundBrush}"
Margin="24,16,12,24"/>
<!-- LoopingSelectors -->
<Grid
Grid.Row="2"
HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Primitives:LoopingSelector
x:Name="SecondarySelector"
Grid.Column="0"
Width="148"
ItemSize="148,148"
ItemMargin="6" >
<Primitives:LoopingSelector.ItemTemplate>
<DataTemplate>
<StackPanel
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Margin="6">
<TextBlock
Text="{Binding MonthNumber}"
FontSize="54"
FontFamily="{StaticResource PhoneFontFamilySemiBold}"
Margin="0,-8"/>
<TextBlock
Text="{Binding MonthName}"
FontSize="20"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
Foreground="{StaticResource PhoneSubtleBrush}"
Margin="0,-2"/>
</StackPanel>
</DataTemplate>
</Primitives:LoopingSelector.ItemTemplate>
</Primitives:LoopingSelector>
<Primitives:LoopingSelector
x:Name="TertiarySelector"
Grid.Column="1"
Width="148"
ItemSize="148,148"
ItemMargin="6">
<Primitives:LoopingSelector.ItemTemplate>
<DataTemplate>
<StackPanel
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Margin="6">
<TextBlock
Text="{Binding DayNumber}"
FontSize="54"
FontFamily="{StaticResource PhoneFontFamilySemiBold}"
Margin="0,-8"/>
<TextBlock
Text="{Binding DayName}"
FontSize="20"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
Foreground="{StaticResource PhoneSubtleBrush}"
Margin="0,-2"/>
</StackPanel>
</DataTemplate>
</Primitives:LoopingSelector.ItemTemplate>
</Primitives:LoopingSelector>
<Primitives:LoopingSelector
Grid.Column="1"
x:Name="PrimarySelector"
Width="148"
ItemSize="148,148"
ItemMargin="6">
<Primitives:LoopingSelector.ItemTemplate>
<DataTemplate>
<StackPanel
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Margin="6">
<TextBlock
Text="{Binding YearNumber}"
FontSize="54"
FontFamily="{StaticResource PhoneFontFamilySemiBold}"
Margin="0,-8"/>
<TextBlock
Text=" "
FontSize="20"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
Foreground="{StaticResource PhoneSubtleBrush}"
Margin="0,-2"/>
</StackPanel>
</DataTemplate>
</Primitives:LoopingSelector.ItemTemplate>
</Primitives:LoopingSelector>
</Grid>
</Grid>
<Primitives:DateTimePickerPageBase.ApplicationBar>
<shell:ApplicationBar IsVisible="True">
<shell:ApplicationBarIconButton
IconUri="/Toolkit.Content/ApplicationBar.Check.png"
Text="DONE"/>
<shell:ApplicationBarIconButton
IconUri="/Toolkit.Content/ApplicationBar.Cancel.png"
Text="CANCEL"/>
</shell:ApplicationBar>
</Primitives:DateTimePickerPageBase.ApplicationBar>
</Primitives:DateTimePickerPageBase>
그냥 xaml을 복사하면 에러가 날것이다.
2개는 꼭 이렇게 수정한다.
xmlns:Primitives="clr-namespace:Microsoft.Phone.Controls.Primitives;assembly=Microsoft.Phone.Controls.Toolkit"
xmlns:Controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
사용법은
<tk:DatePicker x:Name="TkDatePicker" PickerPageUri="/GloryApp;component/Controls/CustomDatePicker.xaml" />
알아내느라 힘들었고 출처 따윈 없다. 검색해도 안 나옴 toolkit 소스를 직접 분석해야 한다.