Reputation: 18379
I want to see if theres a way to combine datetime string format and static strings.
So currently I can format my date and prefix with text like this:
<TextBlock Text="{Binding MyDate StringFormat=Started {0:dd-MMM-yyyy HH:mm}}"
Results in this:
Started 01-Jan-2011 12:00
In the past I've been able to use a static string to keep a common format for my dates; like this (Note no prefixed text):
<TextBlock Text="{Binding MyDate, StringFormat={x:Static i:Format.DateTime}}" />
Where i:Format
is a static class with a static property DateTime
that returns the string "dd-MMM-yyyy HH:mm"
So what I'm asking; is there a way to combine these methods so that I can prefix my date and use the common static string formatter?
Upvotes: 11
Views: 5417
Reputation: 1101
you could use a converter like this:
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource StringFormatConcatenator}">
<Binding Source="Started {0}"/>
<Binding Source="{x:Static i:Format.DateTime}"/>
<Binding Path="MyDate"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
public class StringFormatConcatenator : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string format = values[0].ToString();
for (int i = 0; i < (values.Length - 1) / 2; i++)
format = format.Replace("{" + i.ToString() + "}", "{" + i.ToString() + ":" + values[(i * 2) + 1].ToString() + "}");
return string.Format(format, values.Skip(1).Select((s, i) => new { j = i + 1, s }).Where(t => t.j % 2 == 0).Select(t => t.s).ToArray());
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
return new string[] { };
}
}
You can add as many variables to format as needed in pair of (format, value)
Where:
Binding 0: the complete format without specific variable format ({0:dd-MMM-yyyy HH:mm} replaced by {0})
Binding odd (1,3,5...): variable specific format ("dd-MMM-yyyy HH:mm")
Binding even (2,4,6...): variable value (MyDate)
Upvotes: 1
Reputation: 41403
You could use something like this in place of the Binding:
public class DateTimeFormattedBinding : Binding {
private string customStringFormat = "%date%";
public DateTimeFormattedBinding () {
this.StringFormat = Format.DateTime;
}
public DateTimeFormattedBinding (string path)
: base(path) {
this.StringFormat = Format.DateTime;
}
public string CustomStringFormat {
get {
return this.customStringFormat;
}
set {
if (this.customStringFormat != value) {
this.customStringFormat = value;
if (!string.IsNullOrEmpty(this.customStringFormat)) {
this.StringFormat = this.customStringFormat.Replace("%date%", Format.DateTime);
}
else {
this.StringFormat = string.Empty;
}
}
}
}
}
Then use it like {local:DateTimeFormattedBinding MyDate, CustomStringFormat=Started %date%}
You could probably make the replacement generic also, and set it via a different property (or properties).
Upvotes: 2