简体   繁体   中英

XAML - Converter within Style

I would like to include a Converter for TextBlock' Text property within a Style. I have the following code:

<Page.Resources>
    <converters:StringFormatConverter x:Key="StringFormatConverter" />
    <Style x:Key="StringFormatStyle" TargetType="TextBlock">
        <Setter Property="Text">
            <Setter.Value>
                <Binding>
                    <Binding.Converter>
                        <converters:StringFormatConverter />
                    </Binding.Converter>
                </Binding>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>
...
<TextBlock Text="some text" Style="{StaticResource StringFormatStyle}" />
<TextBlock Text="{Binding AppName}" Style="{StaticResource StringFormatStyle}" />

The problem is that the Convert method of my Converter isn't being called. The style is applied (100% sure of that).

What could be the problem of the converter not being applied to the TextBlock' Text property?

Long story short: I have several double properties in my ViewModel and I would like to display them formatted using a Converter.

PS: My StringFormatConverter looks like this:

public class StringFormatConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value == null)
        {
            return null;
        }

        if (parameter == null)
        {
            return value;
        }

        return string.Format((string)parameter, value);
    }

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

Well, you can't. In style you set text to some invalid binding with only a converter. And later you set it to static text.

If you want to add specific handling to a value and want to avoid code duplicates, use attached variable.

Also note that you're creating two converters actually. One in style and one in resources. So just reference the one from resources, don't need to create it in style again.

Here's attached property sample.

public class TextConv: DependencyObject
{
    public static readonly DependencyProperty TextProperty = 
    DependencyProperty.RegisterAttached(
      "Text",
      typeof(string),
      typeof(TextConv),
      new PropertyMetadata(null, OnValueChanged)
    );
    public static void SetText(UIElement element, string value)
    {
        element.SetValue(TextProperty, value);
    }
    public static string GetText(UIElement element)
    {
        return (string)element.GetValue(TextProperty);
    }
    private static void OnValueChanged(DependencyObject obj,  DependencyPropertyChangedEventArgs args)
   {
       obj.SetValue(TextBlock.TextProperty, args.NewValue.ToString() + "Hello!");
   }
}

And in xaml:

<TextBlock local:TextConv.Text="some text" />

It might not work out of the box but you get the general idea.

If you set the Text property explicitly, that will override the property setter in the style.

Use your converter in the Binding instead of the Style .

Text="{Binding AppName, Converter={StaticResource StringFormatConverterKey}}"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM