I have a String "0214" i would like te present this as 02:14 is this possible in wpf with stringFormat and binding.
If it would be an integer i could do it like bellow but the problem is that the "0" disapears and becomes Int "214" But this is not good for placing in the database because it requires 4 numbers.
<GridViewColumn Header="Start" DisplayMemberBinding="{Binding Start, StringFormat={}{0:00\:00}}"/>
output: '02:14'
StringFormat is not actually used to format strings. It's used to format non-string values into strings.
You can use an IValueConverter however to convert your string into the format you want. Another option would be to alter your data class to expose a read-only FormattedStart property which returns the formatted value.
Use a converter to split the input string and return the two parts separated by a :
Convert to an int and use StringFormat={}{0:00\\:00}} (This should be the equivalent of int.ToString("00':'00")
Related
In analogy to this question, I am curious how to interpret the expression {Binding ''} in WPF.
Note that there are two apostrophes after Binding.
In addition to a Google search I looked at this link provided in the linked question above, but was not able to assert the meaning of the two apostrophes after Binding.
What I came across were String Format expressions, where the apostrophe is used inside double quotes to denote another String expression. But I doubt this is the case here, for this question.
What does this expression mean?
It's equivalent to an empty Path. The apostrophes simply enclose whatever you write between them. So in your case it's a Binding to the DataSource (without a Path) - although I have to say, I've never seen it used that way.
The reason you probably didn't find this in any Bindings related context is because it's actually a feature that is available to all XAML markup extensions (like Binding, Static, StaticResource, etc.).
MSDN: Details about how markup extensions are parsed
The text value of either a MEMBERNAME or STRING is read as follows. Leading whitespace characters are consumed without being represented in the generated token. If the first non-whitespace character is a quote (either Unicode code point 0022, Quotation Mark, or 0027, Apostrophe), the tokenizer proceeds as follows:
The first quote is consumed and is not represented in the token’s value.
The text value becomes the characters up to but not including the next matching quote (i.e. a character of the same code point as the opening quote) that is not preceded by a “\” character. All these characters and also the closing quote are consumed. Any “\” characters in the resulting text value are removed.
Whitespace characters following the closing quote are consumed, and are not represented in the token.
Take this simple (and rather useless) extension for example:
public class StringExtension : MarkupExtension
{
public StringExtension()
{ }
public StringExtension(string value)
{
Value = value;
}
public string Value { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return Value;
}
}
The extension could be used like this (all identical results):
<!-- via constructor (1 argument) -->
<TextBlock Text="{local:String text}"/>
<!-- via constructor (1 argument) -->
<TextBlock Text="{local:String 'text'}"/>
<!-- via empty constructor + named property -->
<TextBlock Text="{local:String Value=text}"/>
<!-- via empty constructor + named property -->
<TextBlock Text="{local:String Value='text'}"/>
So, what are the 's used for? Well for example for leading and trailing Whitespaces.
<!-- no whitespaces -->
<TextBlock Text="{local:String text }"/>
<!-- whitespaces -->
<TextBlock Text="{local:String ' text '}"/>
Okay before I get right into my question does anyone know if there is a tool for building string formats? What I'm thinking is something like a pretty simple user interface where you choose whether you want to display commas, zero values, dollar signs etc and then it spits out the stringformat for you. If there is one I'd love to know about it. If there's not it's the sort of thing people like me would love!
My question is. What is the string format for displaying an integer with comma separators for thousands, no decimal places and nothing for zero values.
I know the string format for an integer with comma separators and no decimal places is:
StringFormat='0,0.'
And I know the string format for displaying nothing for zero values is:
StringFormat='{}{0:#}'
But combining the two has me stumped. Thanks very much!
I'm not 100% sure what you're after, but after comparing your two string formats, I think I know what you're after... please let me know if I am mistaken.
Once again, you almost had what I think you want... how about trying this:
StringFormat='{}{0:#,#.}'
Or just
StringFormat='#,#.' (Just replace the '0' from your example with '#')
These are equivalent. Please note that again, these will both round the number to the nearest integer.
UPDATE >>>
Here are two very useful links to help you with your string.Formats in the future:
Custom Numeric Format Strings
Custom Date and Time Format Strings
ContentStringFormat is separate dependency property out side of Bindig{} assets.
ContentStringFormat='{}{0:#}'
Example:
<Label Content="{Binding Path=MaxLevelofInvestment}" ContentStringFormat="Amount is {0}" />
Custom Date and Time Format Strings on MSDN
Link above seems to use {0:MM/dd/yy H:mm:ss zzz} a lot.
I understand all the letters and formatting options but I can't seem to find what the preceding "0:" is for?
The {0} is a composite formatting placeholder, meaning the first item in the format value list. For details, see this MSDN article, in particular, the section called "Composite Formatting" near the bottom, or the larger article specifically about Composite Formatting. But, to summarize:
In .NET there are two kinds of string formatting you can do: ToString formatting and composite formatting. Both of them use the same custom format string syntax.
When you have a single object, like a DateTime variable, and you call DateTime.ToString() on that object, you can pass a formatting string and it will apply to that object, and format it according to your pattern. But if you have more than one object and you want to build a complex string that includes their values, you instead call String.Format. That function expects a "format string" that contains placeholders where the variable bits go, which look like {0:g} or {5:MM/dd/yy} or something. The remainder of the parameters to String.Format is a list of variables. The {0} placeholder is the first variable, {5} is the 6th, etc.
I'm trying to create a WPF MarkupExtension class that provides translated text from my text translation class. The translation stuff works great, but requires a static method call with a text key to return the translated text. Like this:
ImportLabel.Text = Translator.Translate("import files");
// will be "Dateien importieren" in de or "Import files" in en
Its speciality is that it accepts a counting value to provide better wordings.
ImportLabel.Text = Translator.Translate("import n files", FileCount);
// will be "Import 7 files" or "Import 1 file"
Another example: If something takes yet 4 minutes, it's a different word than if it only takes one minute. If a text key "minutes" is defined as "Minuten" for any number and as "Minute" for a count of 1, the following method call will return the right word to use:
Translator.Translate("minutes", numberOfMinutes)
// will be "minute" if it's 1, and "minutes" for anything else
Now in a WPF application, there's a lot of XAML code and that contains lots of literal texts. To be able to translate them without getting nuts, I need a markup extension which I can pass my text key and that will return the translated text at runtime. This part is fairly easy. Create a class inheriting from MarkupExtension, add a constructor that accepts the text key as argument, store it in a private field, and let its ProvideValue method return a translation text for the stored key.
My real problem is this: How can I make my markup extension accept a counting value in such a way that it's data-bound and the translation text will update accordingly when the count value changes?
It should be used like this:
<TextBlock Text="{t:Translate 'import files', {Binding FileCount}}"/>
Whenever the binding value of FileCount changes, the TextBlock must receive a new text value to reflect the change and still provide a good wording.
I've found a similar-looking solution over there: http://blogs.microsoft.co.il/blogs/tomershamam/archive/2007/10/30/wpf-localization-on-the-fly-language-selection.aspx But as hard as I try to follow it, I can't understand what it does or why it even works. Everything seems to happen inside of WPF, the provided code only pushes it in the right direction but it's unclear how. I can't get my adaption of it to do anything useful.
I'm not sure whether it could be useful to let the translation language change at runtime. I think I'd need another level of bindings for that. To keep complexity low, I would not seek to do that until the basic version works.
At the moment there's no code I could show you. It's simply in a terrible state and the only thing it does is throwing exceptions, or not translating anything. Any simple examples are very welcome (if such thing exists in this case).
Nevermind, I finally found out how the referenced code works and could come up with a solution. Here's just a short explanation for the record.
<TextBlock Text="{t:Translate 'import files', {Binding FileCount}}"/>
This requires a class TranslateExtension, inherited from MarkupExtension, with a constructor accepting two parameters, one String and one Binding. Store both values in the instance. The classes' ProvideValue method then uses the binding it gets, adds a custom converter instance to it and returns the result from binding.ProvideValue, which is a BindingExpression instance IIRC.
public class TranslateExtension : MarkupExtension
{
public TranslateExtension(string key, Binding countBinding)
{
// Save arguments to properties
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
countBinding.Converter = new TranslateConverter(key);
return countBinding.ProvideValue(serviceProvider);
}
}
The converter, say of class TranslateConverter, has a constructor that accepts one parameter, a String. This is my key argument from the TranslateExtension above. It remembers it for later.
Whenever the Count value changes (it comes through the binding), WPF will request its value anew. It seems to walk from the source of the binding, through the converter, to the surface where it's displayed. By using a converter, we don't have to worry about the binding at all, because the converter gets the binding's current value as a method argument and is expected to return something else. Counting value (int) in, translated text (string) out. This is my code.
So it's the converter's task to adapt the number to a formulated text. It uses the stored text key for that. So what happens is basically a kinda backwards data flow. Instead of the text key being the main information and the count value being added to it, we need to treat the count value as the primary information and just use the text key as a side parameter to make it whole. This isn't exactly straightforward, but the binding needs to be the primary trigger. Since the key won't change, it can be stored for good in the instance of the converter. And every occurence of a translated text gets its own copy of the converter, each with an individual key programmed in.
This is what the converter could look like:
class TranslateConverter : IValueConverter
{
private string key;
public TranslateConverter(string key)
{
this.key = key;
}
public object Convert(object value, ...)
{
return Translator.Translate(key, (int) value);
}
}
That's the magic. Add the error handling and more features to get the solution.
I am using a pretty long StringFormat for my bound tooltip and am currenly trying to make it multiline in XAML.
While I was able to make literal ToolTip multiline using
for line breaks I am unable to get it to work with StringFormat.
I am trying to get following code to give me a tooltip with line break:
ToolTipService.Tooltip= {Binding Property,StringFormat='FORMAT WITH LINE BREAK {0}'}
Actually I got correct answer here:
official silverlight forums link
We can use
for line break.
or :
<TextBox Text="{Binding Path=a,
StringFormat='First Line \{0\}
Second Line'}" />
Difference is pretty big.. This one works.
In string format output, have you tried using \r instead to insert carriage returns?
The only reason these encodings exist is to allow special character values to be placed in XML/Xaml.
The
is just an encoding for hex character A = decimal 10 = \r (carriage return).
Another one of interest is
which is character D = decimal 13 = \n (newline).
Note Hex encoding normally requires pairs of digits so
was the actual error.