25


This is my binding (shortened, Command-Property is also bound)

<MenuItem Header="Key" CommandParameter="{Binding StringFormat='Key: {0}', Path=PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>

The Tag-Property of ContectMenu's PlacementTarget is a String like

"Short.Plural"

What i expect to receive in the Command-Handler is:

Key: Short.Plural

But what i acutally receive is:

Short.Plural
H.B.
  • 166,899
  • 29
  • 327
  • 400
Reini
  • 1,233
  • 3
  • 19
  • 34

3 Answers3

35

Label does not use StringFormat but ContentStringFormat. Use it this way:

<TextBlock x:Name="textBlock" Text="Base Text"/>
<Label Content="{Binding Path=Text, ElementName=textBlock}" ContentStringFormat="FORMATTED {0}"/>
tabina
  • 1,095
  • 1
  • 14
  • 37
  • 7
    This should be marked as the answer. Also for a MenuItem to format the Header it's HeaderStringFormat – Viv Mar 14 '13 at 07:44
24

I'm astounded, but my tests just show that StringFormat only applies if the target d-prop is of type String. I've never noticed this before, nor heard it mentioned. I don't have more time to look into it right now, but this seems ridiculous.

Seriously, this works:

<TextBlock x:Name="textBlock" Text="Base Text"/>
<TextBlock Text="{Binding StringFormat=FORMATTED {0}, Path=Text, ElementName=textBlock}"/>

This does not:

<TextBlock x:Name="textBlock" Text="Base Text"/>
<Label Content="{Binding StringFormat=FORMATTED {0}, Path=Text, ElementName=textBlock}"/>

Since Label.Content is not a String.

Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
  • 1
    But commandparameter doesn't seem to recognize the stringformat or at least it doesn't know how to use it, so it only returns the value that is in the binding not the result of the stringformat. – kevindaub Oct 11 '11 at 15:50
1

use Binding Converter:

public class CommandParamConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string)
        {
            return string.Format("Key {0}", value);
        }
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Add it to Windows\UserControl resource:

<Window.Resources>
    <local:CommandParamConverter x:Key="commandParamConverter" />
</Window.Resources>

Refer it in Menu CommandParameter binding:

<MenuItem Header="Key" CommandParameter="{Binding Converter={StaticResource commandParamConverter}, Path=PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
Souvik Basu
  • 3,069
  • 4
  • 28
  • 42
  • Ok, this seems to be the only soloution right now... I'm going to use a converter, but with a ConverterParameter => "StringConcatenationConverter" – Reini Jun 22 '11 at 05:59
  • 1
    @tabina 's answer is better suited for this as it not only removes the requirement for an extra converter but also has the benefit of applying localization easier – Viv Mar 14 '13 at 07:47