かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

検索系の仕上げ

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

前の記事で作った.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}" />

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

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