かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

検索系の仕上げ

前記事:検索系の処理を実装してみよう

前の記事で作った.NET RIA Servicesの検索系の処理ですが、よく見てみるとイマイチなところがあります。よく見てみると、日付がサーバー側とクライアント側で9時間ずれてしまっています。
ということで、ここをどうにかしてみようと思います。

結論としては、サーバ側で作ってるDateTimeのKindをLocalからUtcに変更します。時間のずれは、サーバ側ではLocalとなっているDateTimeのKindが、クライアント側でUtcになっているために発生しています。
さくっと変更してしまいましょう。EmployeesDataStoreクラスのデータを作ってる部分を書き換えます。

static EmployeesDataStore()
{
    // 適当な従業員データを1000件作成
    var r = new Random();
    _employees = Enumerable.Range(0, 1000).Select(i =>
        new Employee
        {
            ID = i,
            Name = "田中 太郎" + i,
            // KindをUtcに明示的に指定する
            EntDate = new DateTime(1950 + r.Next(50), 4, 1, 0, 0, 0, DateTimeKind.Utc),
            Salary = 200000 + r.Next(10) * 10000
        }).ToList();
}

あと、ついでなので、クライアント側で日付の表示がyyyy/MM/ddとなるようにします。これは、EntDateを表示している部分に以下のようなConverterをかませることで実現します。WPFだと、StringFormatというものがBindingに追加されていて、それを指定すればOKなのですが、残念ながらSilverlightにはなさそうなので、Converterで作ることになります。

using System;
using System.Windows;
using System.Windows.Data;

namespace CrudRIAServices
{
    public class FormatConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(string))
            {
                return DependencyProperty.UnsetValue;
            }
            if (value == null)
            {
                return null;
            }
            var format = parameter as string;
            if (format == null)
            {
                return value.ToString();
            }
            return string.Format(string.Format("{{0:{0}}}", format), value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        #endregion
    }
}

そして、MainPage.xamlのResourcesにこのConverterを追加します。

<!-- 書式指定で文字列に変換するフォーマッタ -->
<local:FormatConverter x:Key="formatConverter" />

最後に、DataGridのEntDateを表示する列のBindingに、このConverterを指定します。

<data:DataGridTextColumn
    Header="入社年月日"
    Binding="{Binding EntDate, Converter={StaticResource formatConverter}, ConverterParameter=yyyy/MM/dd}" />

これで、実行すると、以下のような見た目になります。

気になってたけど、スルーしてた日付のズレと表示がいい感じになりました。