Help us understand the problem. What is going on with this article?

[C# / UWP] 書式やカルチャ情報を指定して、DateTime型データのバインディングができるようにする方法

More than 3 years have passed since last update.

こんにちは!ニアです。

今回はUWP(ユニバーサルWindowsプラットフォーム)アプリで、DateTime型データをバインディングする時に、書式カルチャ情報を指定できるようにする方法を紹介します。

1. WPFアプリにおけるDateTime型データのバインディングで、書式やカルチャ情報を指定する

その前に比較として、WPFアプリでの方法を説明します。

コントロールのBindingクラス(System.Windows.Data名前空間)のStringFormatプロパティに書式を、ConverterCultureプロパティにカルチャ情報を指定します。

WPFアプリにおけるDateTime型データのバインディングで、書式とカルチャ情報を指定
<TextBlock Text="{Binding 「DateTime型のデータを返すプロパティ」,
                    StringFormat=「書式」, ConverterCulture=「カルチャ情報」}"/>
MainWindow.xaml
<Window x:Class="DateTimeTest.MainWindow"
        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"
        xmlns:local="clr-namespace:DateTimeTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style x:Key="TestStyle" TargetType="TextBlock">
            <Setter Property="FontSize" Value="16"/>
            <Setter Property="Margin" Value="10, 5"/>
            <Setter Property="Foreground" Value="White"/>
        </Style>
    </Window.Resources>
    <Window.DataContext>
        <local:Sample />
    </Window.DataContext>
    <Grid Background="Black">
        <StackPanel>
            <!-- デフォルト -->
            <TextBlock Style="{StaticResource TestStyle}" 
                       Text="{Binding NowTime}"/>
            <!-- 書式を「yyyy年MM月dd日 HH:mm:ss」と指定した時 -->
            <TextBlock Style="{StaticResource TestStyle}"
                       Text="{Binding NowTime, StringFormat=yyyy年MM月dd日 HH:mm:ss}"/>
            <!-- カルチャ情報を「ja-JP」と指定した時 -->
            <TextBlock Style="{StaticResource TestStyle}"
                       Text="{Binding NowTime, ConverterCulture=ja-JP}"/>
            <!-- カルチャ情報を「en-US」と指定した時 -->
            <TextBlock Style="{StaticResource TestStyle}"
                       Text="{Binding NowTime, ConverterCulture=en-US}"/>
        </StackPanel>
    </Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Windows;

namespace DateTimeTest {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }
    }

    public class Sample {
        public DateTime NowTime { get; set; } = DateTime.Now;
    }
}

BindingDateTimeOnWPF.PNG

2. UWPアプリにおけるDateTime型データのバインディングで、書式やカルチャ情報を指定する

しかしながら、UWPアプリのBindingクラス(Windows.UI.Xaml.Data名前空間)には、StringFormatプロパティやConverterCultureプロパティがありません。

代わりに、IValueConverterインターフェースを継承したConverterクラスを作成し、そのパラメーターに書式やカルチャ情報を渡すようにします。

IValueConverterインターフェースのConverメソッドのパラメーターにあるparameterを書式に、languageをカルチャ情報として使用し、実装していきます。

parameterはobject型なので、object.ToStringメソッドでstring型に変換しておき、languageはCultureInfoクラスのコンストラクターの引数に指定してオブジェクトを生成しておき、それぞれをDateTime.ToStringメソッドの引数に指定します。

// valueはDateTime型データを格納したobject型変数です。
( ( DateTime )value ).ToString( parameter.ToString(), new CultureInfo( language ) )
DateTimeStringConverter.cs
using System;
using System.Globalization;
using Windows.UI.Xaml.Data;

namespace DateTimeTestUWP {
    // 書式やカルチャ情報を指定して、DateTimeオブジェクトを文字列に変換します。
    class DateTimeStringConverter : IValueConverter {

        public object Convert( object value, Type targetType, object parameter, string language ) {
            // valueがDateTime型の時
            if( value != null && value is DateTime ) {
                // parameterを書式、languageをカルチャ情報として使用します。
                // parameterとlanguageが指定されている時
                if( parameter != null && language != null ) {
                    return ( ( DateTime )value ).ToString( parameter.ToString(), new CultureInfo( language ) );
                }
                // parameterのみ指定されている時
                else if( parameter != null ) {
                    return ( ( DateTime )value ).ToString( parameter.ToString() );
                }
                // languageのみ指定されている時
                else if( language != null ) {
                    return ( ( DateTime )value ).ToString( new CultureInfo( language ) );
                }
                // 何も指定されていない時
                return value;
            }
            return null;
        }

        public object ConvertBack( object value, Type targetType, object parameter, string language ) {
            // 中略
        }
    }
}

作成したConverterクラスをPage.Resourcesに追加します。

ConverterクラスをPage.Resourcesに追加
<!-- local : XML名前空間 "using:DateTimeTestUWP" -->
<local:DateTimeStringConverter x:Key="DateTimeStringConverter"/>

コントロールのBindingクラスのConverterParameterプロパティに書式を、ConverterLanguageプロパティにカルチャ情報を指定します。
(ConverterParameterに指定した値がparameterに、ConverterLanguageに指定した値がlanguageに渡されます)

UWPアプリにおけるDateTime型データのバインディングで、書式とカルチャ情報を指定
<TextBlock Text="{Binding 「DateTime型のデータを返すプロパティ」,
                    Converter={StaticResource DateTimeStringConverter}
                    ConverterParameter=「書式」, ConverterLanguage=「カルチャ情報」}"/>
MainPage.xaml
<Page
    x:Class="DateTimeTestUWP.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:DateTimeTestUWP"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.Resources>
        <local:DateTimeStringConverter x:Key="DateTimeStringConverter"/>
        <Style x:Key="TestStyle" TargetType="TextBlock">
            <Setter Property="FontSize" Value="16"/>
            <Setter Property="Margin" Value="10, 5"/>
            <Setter Property="Foreground" Value="{ThemeResource ApplicationForegroundThemeBrush}"/>
        </Style>
    </Page.Resources>
    <Page.DataContext>
        <local:Sample/>
    </Page.DataContext>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel>
            <!-- デフォルト -->
            <TextBlock Style="{StaticResource TestStyle}" 
                       Text="{Binding NowTime}"/>
            <!-- 書式を「yyyy年MM月dd日 HH:mm:ss」と指定した時 -->
            <TextBlock Style="{StaticResource TestStyle}"
                       Text="{Binding NowTime, Converter={StaticResource DateTimeStringConverter},
                                ConverterParameter=yyyy年MM月dd日 HH:mm:ss}"/>
            <!-- カルチャを「ja-JP」と指定した時 -->
            <TextBlock Style="{StaticResource TestStyle}"
                       Text="{Binding NowTime, Converter={StaticResource DateTimeStringConverter},
                                ConverterLanguage=ja-JP}"/>
            <!-- カルチャを「en-US」と指定した時 -->
            <TextBlock Style="{StaticResource TestStyle}"
                       Text="{Binding NowTime, Converter={StaticResource DateTimeStringConverter},
                                ConverterLanguage=en-US}"/>

            <!-- x:Bindでバインディング -->
            <TextBlock Style="{StaticResource TestStyle}" 
                       Text="{x:Bind Path=Sample1.NowTime, Converter={StaticResource DateTimeStringConverter}, ConverterParameter=yyyy年MM月dd日 HH:mm:ss, ConverterLanguage=ja-JP}"/>
        </StackPanel>
    </Grid>
</Page>
MainPage.xaml.ca
using System;
using Windows.UI.Xaml.Controls;

namespace DateTimeTestUWP {
    public sealed partial class MainPage : Page {
        public MainPage() {
            InitializeComponent();
            Sample1 = DataContext as Sample;
        }
        // x:Bind用
        public Sample Sample1 { get; set; }
    }

    public class Sample {
        public DateTime NowTime { get; set; } = DateTime.Now;
    }
}

これで、書式やカルチャ情報を指定して、DateTime型データをバインディングすることができました!

実行結果(Windows 10)

実行結果(Windows 10 Mobile)

それでは、See you next!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away