Forum Xamarin.Forms

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

Using StringFormat in Binding in XAML

TMainTMain USMember ✭✭

How can I use StringFormat in Binding in XAML? For the life of me, I can't find the magic string of characters to enable this - I've tried a gajillion iterations. Here's an example that doesn't work:

<Label Text="{Binding Id, StringFormat=0:N}"/>

救命!

Best Answers

Answers

  • TMainTMain USMember ✭✭

    Yeah, brilliant, thanks @CraigDunn‌

  • TotemikaTotemika ESMember ✭✭

    Hi there, where can I find documentation of the different available formats you can set to StringFormat to? Thanks

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    String.Format is well documented on MSDN and the 'net in generally. Though I think the definitive one-stop shop for it is the SteveX page. Google "SteveX format" and the top result should be for 'SteveX Compiled' going here:
    http://blog.stevex.net/string-formatting-in-csharp/

  • MattButlerMattButler USUniversity ✭✭
    edited November 2016

    Is it possible to combine values with StringFormat in Xaml? For instance, I'm binding a list of objects to a ListView. The objects have object.name and object.description properties. Can I do something like?

    <Label Text="{Binding object.name, object.description, StringFormat='Name = {0}, Description = {1}'}"/>

    I tried that and it didn't work... :(

  • NMackayNMackay GBInsider, University admin

    @MattButler

    Use a value converter by passing the object through and returning the formatted string, you can do it in the VM but that's really for just serving up the data and handling responses/business logic, not data presentation.

  • tuyenvtuyenv VNUniversity ✭✭✭

    thanks in advance

  • Felix.xFelix.x USMember ✭✭

    For example, to display a float with 2 decimals, it should be StringFormat='{0:F2}'

  • ZoliZoli NLMember ✭✭✭

    It's not a good idea to hardcode the formatting string into the XAML.
    Is it possible to get the format string from a static resource?

    Like I have

    class Const
         public static string NUMBER_FORMAT = "{0:0.00}";
    

    And use this in the XAML , something like

    <Label Text="{Binding TheNumber, StringFormat='"{x:Static local:Const.NUMBER_FORMAT}"'}"/>
    
  • Felix.xFelix.x USMember ✭✭

    too bad it's different from WPF's version of {}{0:F1}. But I like Xamarin.Forms version of ''.

  • joseantonyjoseantony USMember

    can i add a string from resource while binding a value in a string format in xaml.
    Like

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Yes you can

  • joseantonyjoseantony USMember
    edited February 2018

    @ClintStLaurent how?, Can you help me. thanks in advance

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @joseantony said:
    @ClintStLaurent how?, Can you help me. thanks in advance

    What have you tried so far, and what errors did you get?

  • joseantonyjoseantony USMember

    Text="{Binding OldValue,StringFormat='ORI:{0:F0}'}"

    i tried this, but i save this "ORI:" in resource .
    Text="{Binding OldValue,StringFormat='x:Static i18n:Strings.OriginalValue{0:F0}'}"

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Just putting 'ORI' in the string isn't going to tell the code that its a resource. Why would it choose to look for a resource called 'ORI' instead of just outputting the text 'ORI'?

    It looks like you're trying to do what @Zoli already described

    <Label Text="{Binding TheNumber, StringFormat='"{x:Static local:Const.NUMBER_FORMAT}"'}"/>

    See how you have to specify that you are referring to a static reference

  • joseantonyjoseantony USMember

    @ClintStLaurent i tried this Text="{Binding OldValue,StringFormat='"{x:Static i18n:Strings.RecommendedValue}{0:F0}"'}"
    but not working :(

  • PaulParkinsPaulParkins USMember ✭✭

    The answer given by Craig seems straightforward enough. But I am finding that the compiler will not accept this without some constant prefix as per Stavros' reply.

    This is not accepted
    <Label Text="{Binding FiscalCounts.Coins[0].CountValue, StringFormat='{0:C}'}" />

    But this is accepted (note the extra space before the format specifiers)
    <Label Text="{Binding FiscalCounts.Coins[0].CountValue, StringFormat=' {0:C}'}" />

    Without the space it gives me 4 errors. Tried to post an image but the forums won't let me (newbie here). Basically the errors each say a character is expected: 1) An unprintable char represented by a square 2) An unprintable char that doesn't display, 3) A single quote char 4) A '}' char

    I can accept having an unwanted space in there, but does anybody understand why I have to do this?

    Thanks

    Paul

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @PaulParkins said:
    This is not accepted
    <Label Text="{Binding FiscalCounts.Coins[0].CountValue, StringFormat='{0:C}'}" />

    Personally I'd disagree with you to this point. Because we have a couple dozen uses just like this and they work fine.
    StringFormat='Dog(s): {0}'}"
    ..
    <Label Text="{Binding IdNumber, StringFormat='#{0}'}" />
    ...
    <Label Text="{Binding UpdateTime, StringFormat='{}{0:hh\\:mm tt}'}" TextColor="Black" FontSize="Medium"/>
    ...

    <Label Text="{Binding City, StringFormat='{0}, '}" TextColor="Black" FontAttributes="Bold"/>
    <Label Text="{Binding State, StringFormat='{0} '}" TextColor="Black" FontAttributes="Bold"/>
    

    And a bunch of other variations. I mean it could be possible that its something ONLY with the :C format. But that would be a heck of a specific outlyer case.

    But I am finding that the compiler will not accept this without some constant prefix as per Stavros' reply.

    I'm thinking that's some issue with your IDE/Visual Studio and not XAML or use of string.format because it works for others.

  • PaulParkinsPaulParkins USMember ✭✭

    Hi Clint, thanks for your input.
    Every one of your examples includes either a constant prefix or a postfix to the format specifiers. Would your examples still work if they did not include the constants I wonder?

    We both agree the syntax should be accepted, but for me it is not. So even if it is my IDE/VS, then the question is does anybody understand why these might be playing up, and how to fix? I really don't want to reinstall everything in the vague hope this might go away.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Testing with your exactly markup and a couple classes I made to support what I saw in your markup.

    This is not accepted
    <Label Text="{Binding FiscalCounts.Coins[0].CountValue, StringFormat='{0:C}'}" />

    Page XAML

            <StackLayout Orientation="Horizontal">
                <Label Text="Test"
                       TextColor="{StaticResource ColorBlue}" />
                <Label Text="{Binding FiscalCounts.Coins[0].Name,
                                      StringFormat='{0}'}" />
                <Label Text="{Binding FiscalCounts.Coins[0].CoinValue,
                                      StringFormat='{0:C}'}" />
            </StackLayout>
    

    Coin class

        public class Coin : BindableObject
        {
    
            #region Name (string)
            private string _Name;
            public string Name
            {
                get
                {
                    //if (_Name == null) Name = new string();
                    return _Name;
                }
    
                set
                {
                    if (_Name == value) return;
                    _Name = value;
                    OnPropertyChanged();
                }
            }
            #endregion Name  (string)
    
    
            #region CoinValue (Double)
            private Double _CoinValue;
            public Double CoinValue
            {
                get
                {
                    //if (_CoinValue == null) CoinValue = new Double();
                    return _CoinValue;
                }
    
                set
                {
                    if (_CoinValue == value) return;
                    _CoinValue = value;
                    OnPropertyChanged();
                }
            }
            #endregion CoinValue  (Double)
    
    
        }
    

    ViewModel property for binding

            #region FiscalCollection (FiscalObject)
            private FiscalObject _FiscalCounts;
            public FiscalObject FiscalCounts
            {
                get
                {
                    if (_FiscalCounts == null) FiscalCounts = new FiscalObject();
                    return _FiscalCounts;
                }
    
                set
                {
                    if (_FiscalCounts == value) return;
                    _FiscalCounts = value;
                    OnPropertyChanged();
                }
            }
            #endregion FiscalCollection  (FiscalObject)
    

    ViewModel Constructor

    There's some other stuff in there from other testing like the WidgetCollection. I keep a

            public TestingVM()
            {
                Frog = "Testing";
    #if DEBUG
                WidgetCollection.Add(new Widget() {Name = "One"});
                WidgetCollection.Add(new Widget() {Name = "Two"});
                WidgetCollection.Add(new Widget() {Name = "Three"});
                WidgetCollection.Add(new Widget() {Name = "Four"});
                WidgetCollection.Add(new Widget() {Name = "Five"});
                WidgetCollection.Add(new Widget() {Name = "Six"});
    #endif
    
                FiscalCounts.Coins.Add(new Coin() { Name = "Quarter", CoinValue = .25 });
                FiscalCounts.Coins.Add(new Coin() { Name = "Dime", CoinValue = .10 });
                FiscalCounts.Coins.Add(new Coin() { Name = "Nickle", CoinValue = .05 });
                FiscalCounts.Coins.Add(new Coin() { Name = "Penny", CoinValue = .01 });
            }
    
            #region FiscalCollection (FiscalObject)
            private FiscalObject _FiscalCounts;
            public FiscalObject FiscalCounts
            {
                get
                {
                    if (_FiscalCounts == null) FiscalCounts = new FiscalObject();
                    return _FiscalCounts;
                }
    
                set
                {
                    if (_FiscalCounts == value) return;
                    _FiscalCounts = value;
                    OnPropertyChanged();
                }
            }
            #endregion FiscalCollection  (FiscalObject)
        } 
    

    No compile problem

    That's the first thing to note. The problem/error you describe for compiling doesn't happen. Which makes me wonder if you have some random character or misplaced closing tag or something else wrong with your XAML.

    Screenshot

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Observation:
    You're specifying an upper-case C, which is working for now. But currency is actually a lower-case 'c'.
    http://blog.stevex.net/string-formatting-in-csharp/

    Maybe you're bumping up against something for your localization/regionalization on the off chance you're not in the USA using US-en as your culture??

  • ASteklAStekl Member

    @PaulParkins Hi Paul, I just created an account because you and I were having the same problem. I get the same errors you talk about, but I have just been ignoring them since it still allowed me to run my code without causing problems. Your posts encouraged me to look for an answer, and I believe I have found one. You need to add '{}' at the beginning of the StringFormat. This site won't let me post links yet, but you can look for the StackOverflow post titled: "StringFormat shows error in Designer, but not after compiling"

  • PaulParkinsPaulParkins USMember ✭✭

    @ClintStLaurent Thanks for putting so much effort into attempting to reproduce my problem. I cannot deny that the code you have appears to work, but also I cannot deny that my compiler does complain at my code. In fact, having read the article that AStekl referred, I wonder if I did not describe the problem sufficiently (or if in fact I have learnt more since).

    It seems to me that with my format string as I originally quoted, the compiler does not accept it and gives me 4 errors of "Error XLS0112" as per that article. Now this error appears from the background compiling that Visual Studio appears to do as I develop my code. But I have now determined that if I build my application, those errors go away and the application will run. But as soon as I make any (even unrelated) changes to that xaml file, the errors re-appear.

    So the problem now appears to be not that my string formatting is not accepted at all, it just isn't accepted by background compilation, and is only accepted on a full build.

    Thankyou also for pointing out my incorrect use of 'C' for currency instead of 'c'. You are quite correct, but in practice it seems to make no difference whether I use 'C' or 'c'.

    @AStekl Thanks for the link. I don't understand why the '{}' prefix, but there is another article which seems to support it (search "XAML StringFormat syntax for decimal places"). But in fact the '{}' prefix solution is very similar to my own "fix" by adding a space prefix. Both of the following do work at runtime, and eliminate the XLS0112 error at designtime.
    Text="{Binding FiscalCounts.Coins[2].CountValue, StringFormat='{}{0:c}'}"
    Text="{Binding FiscalCounts.Coins[2].CountValue, StringFormat=' {0:c}'}"

    So I am not understanding any better, but I have two suitable workarounds I can apply.

    Thanks all

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @PaulParkins Just to confirm... When you say "My compiler" - you are talking about VIsual Studio 2015 or 2017... Right?

  • ASteklAStekl Member

    @PaulParkins In the article I mentioned, I wanted you to focus on the answer. In it he mentions that you can not start the StringFormat with a formatting request, so you must use the delimiter "{}" in front of it. For this reason, I do not believe this to be a work around. While your method works as well, I prefer to use the delimiter so that the text isn't off centered by the extra space.

  • PaulParkinsPaulParkins USMember ✭✭
    edited October 2018

    @ClintStLaurent Yes Clint, Visual Studio 2017 version 15.7.5

    @AStekl I also went for that version for the same reasons as you. I am just unsure what the delimiter is separating

Sign In or Register to comment.