user3685285
user3685285

Reputation: 6566

WPF StringFormat in Binding doesn't work in code behind

I am trying to create a DataTemplate programmarically 100% in the codebehind. Everything works perfectly, except the StringFormat on the text binding in the textblocks doesn't work.

Normally in xaml, I would accomplish this like so:

<TextBlock Text={Binding MyProperty, StringFormat=0.0} />

so I assumed I could just set the StringFormat property of the Binding object, which I did. I verified that it gets set correctly, and it does, but my view still doesn't reflect the formatting. Why?

Here is an excerpt from my code: a function that creates a DataTemplate dynamically for me. Literally everything else works perfectly, from setting the binding path to the ivalue converters, and everything. Just not the string format.

string propertyName = "myPropertyName";
FrameworkElementFactory textBlock = new FrameworkElementFactory(typeof(TextBlock));

// the property I want is owned by myObject, which is a property of the datacontext
string bindingString = String.Format("myObject[{0}]", propertyName); 
Binding binding = new Binding(bindingString)
{
    Mode = BindingMode.OneWay,
    Converter = (IValueConverter)Application.Current.FindResource("InvalidValuesConverter"),
    StringFormat = "{0:F1}" // <-- Here is where I specify the stringFormat. I've also tried "0.0"
};

textBlock.SetBinding(TextBlock.TextProperty, binding);

Upvotes: 2

Views: 1888

Answers (1)

Looks like what you're seeing is that the StringFormat is being applied, but it doesn't do numeric formatting on the string values your converter is returning. Since the particular format you're using has nothing in it but numeric formatting, in effect the converter + StringFormat processing is a no-op in the non-NaN case. The quickest way to test this assumption is to give it a format like N={0:#}, which I did. It formatted decimal 3.5 as "N=4" and string "3.5" as "N=3.5".

Naturally, values are passed through the converter before they're formatted.

Since the only purpose of your converter to substitute an empty string for Double.NaN, I'd advise that your converter only convert to string in the NaN case, and otherwise return the double value as-is. Convert returns object so that's no problem.

For simplicity, the code below assumes that you can count on value always being double.

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (double.IsNaN((double)value)) 
            ? "" 
            : value;
    }

Upvotes: 2

Related Questions