11

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?

2 Answers 2

2

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).

Sign up to request clarification or add additional context in comments.

1 Comment

I think this is the only alternative if you want to fill both the value and the format of the value. I tried string.Format("Started {0:{1}}", DateTime.Now, "dd-MMM-yyyy HH:mm") and got an exception.
1

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.