How to display dynamic culture formatted number in a WPF UserControl
Asked Answered
S

2

6

I would like to dynamically set the culture format of the Number textblock with culture and number values passed through to MyUserControl. The MyCulture and Number values are passed to MyCustomControl and will be of the form "en-GB", "en-US" etc.

I did something similar in asp.NET MVC with an extension method but need help for how to piece this together in WPF.

Example MVC Extension Method

public static MvcHtmlString CulturedAmount(this decimal value, 
    string format, string locale)
{
    if (string.IsNullOrEmpty(locale))
        locale = HttpContext.Current.Request.UserLanguages[0];

    return MvcHtmlString.Create(value.ToString(format, 
        CultureInfo.CreateSpecificCulture(locale)));
}

Window

//MyMoney is a decimal, MyCulture is a string (e.g. "en-US")
<MyCustomControl Number="{Binding MyMoney}" Culture="{Binding MyCulture}" 
    Text="Some Text" />

MyCustomControl

<StackPanel>
    <TextBlock Text="{Binding Number, ElementName=BoxPanelElement, 
        StringFormat={}{0:C}}" /> //display this with specific culture
    <TextBlock Text="{Binding Text, ElementName=BoxPanelElement}" />
</StackPanel>
Spermogonium answered 22/8, 2011 at 19:30 Comment(0)
W
8

If I understand your question correctly you want to bind the culture for a specific TextBlock.

You can't bind the properties of a Binding so binding ConverterCulture won't work.

There is a Language property on FrameworkElement which works fine to set like this

<TextBlock Language="en-US"
           Text="{Binding Number,
                          ElementName=BoxPanelElement,
                          StringFormat={}{0:C}}"/>

However, when trying to bind this property I get a weird exception
I'm probably going to ask a question on this exception myself

Binding for property 'Language' cannot use the target element's Language for conversion; if a culture is required, ConverterCulture must be explicitly specified on the Binding.

According to this answer by Thomas Levesque this should be possible though so maybe I did something wrong.. WPF xml:lang/Language binding

All I got working was using an attached behavior which in turn updated Language when MyCulture updated.

<TextBlock local:LanguageBehavior.Language="{Binding MyCulture}"
           Text="{Binding MyNumber,
                          ElementName=BoxPanelElement,
                          StringFormat={}{0:C}}"/>

LanguageBehavior

public class LanguageBehavior
{
    public static DependencyProperty LanguageProperty =
        DependencyProperty.RegisterAttached("Language",
                                            typeof(string),
                                            typeof(LanguageBehavior),
                                            new UIPropertyMetadata(LanguageBehavior.OnLanguageChanged));

    public static void SetLanguage(FrameworkElement target, string value)
    {
        target.SetValue(LanguageBehavior.LanguageProperty, value);
    }
    public static string GetLanguage(FrameworkElement target)
    {
        return (string)target.GetValue(LanguageBehavior.LanguageProperty);
    }
    private static void OnLanguageChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement element = target as FrameworkElement;
        element.Language = XmlLanguage.GetLanguage(e.NewValue.ToString());
    }
}
Wrung answered 22/8, 2011 at 20:38 Comment(4)
@Spermogonium Liddle: Interesting! Did you do anything special to get it to work?Wrung
Not at all, just added Language="en-US" to the TextBlock - .net 4.0.Spermogonium
@Spermogonium Liddle: Try setting Language="{Binding Source='en-US'}". Or in your case, Language="{Binding MyCulture}".Wrung
Looks like you can bind directly to the Language property if you declare MyCulture as XmlLanguage rather than stringAmharic
I
1

It seems like a converter is the answer. The interface includes a values for culture.

    Convert(object value, Type targetType, object parameter, CultureInfo culture) 

But I could not find syntax for passing culture. Sorry this is not a full and tested answer but I ran out of time.

URL on binding culture.
http://msdn.microsoft.com/en-us/library/system.windows.data.binding.converterculture.aspx

The syntax for passing a a parameter is:

    Converter={StaticResource colorConverter}, ConverterParameter=GREEN}" 

You may need to pass culture as a string using ConverterParameter.

I agree with Meleak that cannot bind the parameter to a converter. Gave him a +1. But I think you can fool it with a MultiBinding converter.

    <TextBlock Name="textBox2" DataContext="{StaticResource NameListData}">
        <TextBlock.Text>
            <MultiBinding Converter="{StaticResource myCutlureConverter}"
              ConverterParameter="FormatLastFirst">
                  <Binding Path="InputValue"/>
                  <Binding Path="CultureTxt"/>
            </MultiBinding>
         </TextBlock.Text>
    </TextBlock>
Intellectualism answered 22/8, 2011 at 20:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.