dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.
MIT License
7.08k stars 1.17k forks source link

Binding with StringFormat doesn't work for tooltips #681

Open bugproof opened 5 years ago

bugproof commented 5 years ago

Probably an old bug: https://stackoverflow.com/questions/197095/wpf-binding-with-stringformat-doesnt-work-on-tooltips

Actual behavior:

StringFormat is ignored

<Button Content="Today" ToolTip="{Binding Source={x:Static sys:DateTime.Now}, StringFormat=YYYY}" />

Expected behavior:

It should work.

miloush commented 5 years ago

Since TimeSpan (or anything else) is directly assignable to the ToolTip property (which is of type object), no conversion to string needs to happen, so the StringFormat is not used. You could claim the same issue for the Tag property.

I would consider it not only a breaking change, but also a bug if it were otherwise. If you want to use a string for tooltips, provide a string, or use a TextBlock to show it.

airbreather commented 5 years ago

I would consider it not only a breaking change, [...]

No arguments from me on this point, but...

[...] but also a bug if it were otherwise.

I disagree with this point. Strategic 3.0 GA roadmap concerns aside, I imagine that this is a stumbling block for a very large fraction of WPF developers who have ever wanted to set something like the Content of some ContentControl or FrameworkContentElement (etc., etc.) to a binding from a non-string property with a particular format.

IMO, if a developer explicitly provides a StringFormat on their binding, then they have made their intention very clear: they want the binding to essentially act as if the source is a string that was the result of running:

string.Format(bindingStringFormat, bindingSource)

The proposed change would be (if I understand the current behavior correctly) that rather than having StringFormat "turn on" only when the source is of a type that's incompatible with the destination type, it should instead "turn on" when the destination type is of any type that's compatible with string. So string, object, or any of the interfaces that System.String implements.

It would indeed be a breaking change, and I absolutely expect it to be a "future" milestone kind of thing, with the strategic goals for 3.0 GA having been made abundantly clear, but IMO the potential value is high, and there is probably not much risk of breaking applications that actually depend on this behavior.

chucker commented 4 years ago

This leads to a fair bit of confusion, since if you google "wpf stringformat", you get the impression that it should just work™. (The top Google result for me right now is a nice article and sounds terrific — but makes no mention that this isn't actually supported for Label.)

Can we add a warning to the XAML editor if you try to do this?

            <Label Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" d:Content="123"
                   Content="{Binding CurrentData.Angle, StringFormat={}{0}°}" />

Or, even better, an offered refactor to this?

            <Label Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" d:Content="123"
                   Content="{Binding CurrentData.Angle}" ContentStringFormat="{}{0}°" />