Skip to content

Instantly share code, notes, and snippets.

@kurema
Last active June 25, 2018 15:44
Show Gist options
  • Save kurema/d7859814b3cdbfa768a417416c1f53be to your computer and use it in GitHub Desktop.
Save kurema/d7859814b3cdbfa768a417416c1f53be to your computer and use it in GitHub Desktop.

TimeSpanFormatValueConverter

概要

XamlのBindingのStringFormatはTimeSpanでろくに機能しないようなので自前実装。日付を消したりできる。

説明

ConverterParameterでレイアウト指定。

表記 内容
[Days][Hours][Milliseconds][Minutes][Seconds][Ticks] TimeSpanの時分秒などの要素で単純に表示
[TotalDays] etc TimeSpanを時分秒単位で表示
[TotalDaysFloor] etc TimeSpanを時分秒単位で切り捨てて表示(整数)
[TotalDays:\{0:00\}] etc TimeSpanの表示をString.Format()の形式で表示。 {0:00}では0埋め二桁
[if:TotalMinutesFloor:words...] TimeSpanの時分秒が0以上ならwords...を表示

基本的に入れ子には非対応。ただし[Time]→[Time:Layout]→[if:Time:words]の順で処理するので後者に入れ子はできる。 また単なる[]もそのまま表示できるはず。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vc="clr-namespace:SampleApp.ValueConverters"
             x:Class="SampleApp.Views.MainPage"
             >
    <ContentPage.Resources>
        <vc:TimeSpanFormatValueConverter x:Key="tsfVC" />
    </ContentPage.Resources>
<Label Text="{Binding Path=ElapsedTime,Converter={StaticResource tsfVC},ConverterParameter='経過時間 : [if:TotalMinutesFloor:[TotalMinutesFloor:\{0:00\}]分][Seconds:\{0:00\}]秒'}" />

,ConverterParameter='経過時間 : [if:TotalMinutesFloor:[TotalMinutesFloor:\{0:00\}]分][Seconds:\{0:00\}]秒'で0m2sなら02秒、02m5sなら02分05秒、1h23m45sなら72分45秒の表示になる。 2m0sなら02分00秒になる。

public class TimeSpanFormatValueConverter: Xamarin.Forms.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null || !(value is TimeSpan))
{
return "";
}
if (parameter == null || !(parameter is string)) return ((TimeSpan)value).ToString();
else return FormatTimeSpan((TimeSpan)value, (string)parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public static string FormatTimeSpan (TimeSpan ts, string tx)
{
var dic = new Dictionary<string, double>()
{
{ nameof(ts.Days),ts.Days },
{ nameof(ts.Hours),ts.Hours },
{ nameof(ts.Milliseconds),ts.Milliseconds },
{ nameof(ts.Minutes),ts.Minutes },
{ nameof(ts.Seconds),ts.Seconds },
{ nameof(ts.Ticks),ts.Ticks },
{ nameof(ts.TotalDays),ts.TotalDays },
{ nameof(ts.TotalHours),ts.TotalHours },
{ nameof(ts.TotalMilliseconds),ts.TotalMilliseconds },
{ nameof(ts.TotalMinutes),ts.TotalMinutes },
{ nameof(ts.TotalSeconds),ts.TotalSeconds },
{ nameof(ts.TotalDays)+nameof(Math.Floor), Math.Floor(ts.TotalDays) },
{ nameof(ts.TotalHours)+nameof(Math.Floor),Math.Floor(ts.TotalHours) },
{ nameof(ts.TotalMilliseconds)+nameof(Math.Floor),Math.Floor(ts.TotalMilliseconds) },
{ nameof(ts.TotalMinutes)+nameof(Math.Floor),Math.Floor(ts.TotalMinutes) },
{ nameof(ts.TotalSeconds)+nameof(Math.Floor),Math.Floor(ts.TotalSeconds) },
};
{
var reg = new System.Text.RegularExpressions.Regex(@"\[(\w+)\]");
tx = reg.Replace(tx, new System.Text.RegularExpressions.MatchEvaluator((m) => { if (dic.ContainsKey(m.Groups[1].Value)) return dic[m.Groups[1].Value].ToString(); else return m.Value; }));
}
{
var reg = new System.Text.RegularExpressions.Regex(@"\[(\w+):([^\[\]]+)\]");
tx = reg.Replace(tx, new System.Text.RegularExpressions.MatchEvaluator((m) => { if (dic.ContainsKey(m.Groups[1].Value)) return String.Format(m.Groups[2].Value, dic[m.Groups[1].Value]); else return m.Value; }));
}
{
var reg = new System.Text.RegularExpressions.Regex(@"\[if:(\w+):([^\[\]]+)\]");
tx = reg.Replace(tx, new System.Text.RegularExpressions.MatchEvaluator((m) => { if (dic.ContainsKey(m.Groups[1].Value) && dic[m.Groups[1].Value]>0) return m.Groups[2].Value; else return ""; }));
}
return tx;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment