I have a label and im using binding and a FormatString as such:
<Label Text="{Binding buying_price , StringFormat='{0} EUR'}">
The label's text is bound to a double in my ViewModel, what im getting on the label is something like this: 10000 EUR, what i want to get is 10 000 EUR, and 12 501 005 EUR for example (without the trailing .00).
I tried StringFormat='{0:C2} EUR' and StringFormat='{0:N} EUR' and StringFormat='{0:n} EUR' but non of them gave me a good result.
I did not make it work in xaml, while when I use a convert and use string format in code behind, it works as excepted:
<ContentPage.Resources>
<ResourceDictionary>
<local:thousandsSeparatorConverter x:Key="thousandsSeparator"/>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<!-- Place new controls here -->
<Label Text="{Binding date, Converter={StaticResource thousandsSeparator}}" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
</StackLayout>
And the local:thousandsSeparatorConverter :
public class thousandsSeparatorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string s = value as string;
double number = double.Parse(s);
// Gets a NumberFormatInfo associated with the en-US culture.
NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;
// Displays the same value with a blank as the separator.
nfi.NumberGroupSeparator = " ";
Console.WriteLine(number.ToString("N0", nfi));
string convertedNumber = number.ToString("N0", nfi);
return convertedNumber;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
Try using StringFormat='{}{0:#,##,#}' depending on your culture you may need to change it in the code-behind if you get a result of 10,000 EUR instead of 10 000 EUR, in the former the , is a thousands separator not a comma.
You may want to take a look at the complete documentation for available numeric format string.
Related question helpful for culture: How would I separate thousands with space in C#
Related
I am developing a chat application in Xamarin Forms and I am trying to add conditional formatting depending on whether it is an incoming or outgoing message.
This is my XAML:
<Frame
Margin="1"
Padding="0"
x:Name="FrameRef"
x:DataType="model:ChatMessage">
<Frame
CornerRadius="10"
Padding="7"
BackgroundColor="LightBlue"
HasShadow="false"
Margin="10,10,80,0">
<Frame.Triggers>
<DataTrigger
TargetType="Frame"
Binding="{Binding Source={x:Reference FrameRef}, Path=x:DataType.From}" Value="+1456456456">
<Setter Property="BackgroundColor" Value="Yellow"/>
</DataTrigger>
</Frame.Triggers>
When I use Path="Margin" and Value="1" it works.
I am now trying to make it work with the Path being x:DataType="model:ChatMessage" and checking the 'from'-field (indicating if the message was incoming or outgoing).
I'm not sure the Data Trigger is quite right for this application, since you're really depending on a data type and not really the content per se of another field. From the documentation:
The DataTrigger class is suitable for checking values on other controls, as well as any property on the control to which it has been added.
What you probably want instead is a Value Converter that handles locating a StaticResource and applying a style for you based on the message type. Full Microsoft Documentation here.
On your XAML element, you'd do something like this:
<Frame Style="{Binding foo, Converter={StaticResource FooToStyleConverter}}"/>
Your converter would work something like this:
public class FooToStyleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var someValue = (DataTye)value; // Convert 'object' to whatever type you are expecting
// evaluate the converted value
if (someValue.From != null && someValue.From == Enum.SomeoneElse)
return (Style)App.Current.Resources["StyleReceived"]; // return the desired style indicating the message is from someone else
return (Style)App.Current.Resources["StyleSent"]; // return a style indicating the message is from the sender
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// Usually unused, but inverse the above logic if needed
throw new NotImplementedException();
}
}
Lastly, set up your converter as a Static Resource in App.xaml (or as a local resource on the page) so your page can properly reference it
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataBindingDemos">
<ContentPage.Resources>
<ResourceDictionary>
<local:FooToStyleConverter x:Key="FooToStyleConverter" />
....
I know that we can directly bind properties in Xaml.
But My requirement is bit different. I want full control on binding data.
So I am looking for adapter type approach. I want to display some elements based on number of lines in textblock of that item. Here i cant use value converter because at that time my UI won't be ready and I cant find number of lines of each textblocks.
I will explain with example, let's suppose I want to change time format from hh:mm:ss to hh:mm during binding.
First, I will create public class that implements IValueConverter.
for example :-
public class RemoveSecondsInTime : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
string date = value as string;
date = date.Substring(0, date.Length - 3);
return date;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Second, To use this converter class, we need to add this converter class in page resources.
for example :-
<Page.Resources>
<local:RemoveSecondsInTime x:Key="ChangeTimeFormat" />
</Page.Resources>
Third, We will create create our ListView as following :-
<ListView>
<ListView.ItemTemplate>
<DataTemplate >
<TextBlock Text="{Binding TimeWithSeconds, Converter {StaticResource ChangeTimeFormat}}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So, TimeWithSeconds will pass as "value" parameter in Convert function, Convert function will return formatted string to be displayed in textBox.
References :-
1) https://channel9.msdn.com/Series/Windows-Phone-8-1-Development-for-Absolute-Beginners/Part-25-Advanced-Binding-with-Value-Converters
2) https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.data.ivalueconverter
I'm trying to bind the PlayerFramework.MediaPlayer.CanPause Property to a Button in my windows 10 universal app. This works using the default font, but when I switch to Segoe MDL2 to get those fancy icons the button shows garbage.
<mmppf:MediaPlayer x:Name="mediaElement">
...
<Button Name="btnPlay"
Style="{StaticResource transportStyle}" Content="{Binding CanPause, ElementName=mediaElement, Converter={StaticResource CanPauseToPlayPauseConverter}}"/>
This is from the converter:
public object Convert(object value, Type targetType, object parameter, string language)
{
bool canPause = (bool)value;
if (canPause)
return #"";
// "play"
return "";
}
...and this from the button style:
<Style x:Name="transportStyle" TargetType="Button">
<!-- <Setter Property="FontFamily" Value="Segoe MDL2 Assets" />-->
</Style>
After disabling the Setter property the button shows the expected value
which, directly set as the button content, shows the play symbol.
Any ideas why this doesn't work?
edit: Copying the character from the character table and returning it does work.
is a unicode character escape sequence in XML (and hence also in XAML). In C# it is written as \uE102.
So the converter should return strings (or characters) with proper C# unicode character escape sequences:
public object Convert(object value, Type targetType, object parameter, string language)
{
return (bool)value ? "\uE769" : "\uE102";
}
You have to return a char not a string:
public object Convert(object value, Type targetType, object parameter, string language)
{
bool canPause = (bool)value;
if (canPause)
return '\xE769';
// "play"
return '\xE102';
}
I am trying to format my string to have commas every 3 places, and a decimal if it is not a whole number. I have checked roughly 20 examples, and this is the closest I have come:
<TextBlock x:Name="countTextBlock" Text="{Binding Count, StringFormat={0:n}}" />
But I get a The property 'StringFormat' was not found in type 'Binding'. error.
Any ideas what is wrong here? Windows Phone 8.1 appears to differ from WPF, because all of the WPF resources say that this is how it is done.
(The string is updated constantly, so I need the code to be in the XAML. I also need it to remain binded. Unless of course I cannot have my cake and eat it too.)
It seems that, similar to Binding in WinRT, Binding in Windows Phone Universal Apps doesn't have StringFormat property. One possible way to work around this limitation is using Converter as explained in this blog post,
To summarize the post, you can create an IValueConverter implmentation that accept string format as parameter :
public sealed 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();
}
}
Create a resource of above converter in your XAML, then you can use it like this for example :
<TextBlock x:Name="countTextBlock"
Text="{Binding Count,
Converter={StaticResource StringFormatConverter},
ConverterParameter='{}{0:n}'}" />
I have a piece of code for a Text Box in a XAML File. The text box takes as input Numeric Value.Below is the piece of code:-
<TextBox Text="{Binding Path=Revenue, StringFormat=c0, Mode=TwoWay, Converter={StaticResource NullableConverter}, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Grid.Column="3" Grid.Row="2"/>
However if I input 5 and tab out the input does not become 5 $. However, on saving the data in the page and loading the page the formatting is intact. Any thoughts on this ??
please remove the converter and try it, you should get it. should be something wrong with converter.
this is what I tried for Nullable Converter it worked.
public class NullableConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return 0;
else
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
If you are using SL5 I think this is a bug, the StringFormat is not triggered when the binding is updated. For more details here is the MS connect issue. You can check the workaround it might help you solving the problem.