How to use stringformat in multibinding in WPF XAML - wpf

As you know StringFormat is of great importance for data representation in WPF. My problem is how to use StringFormat when multibinding in WPF?
If I give a very simple example:
We have variables,which are A and B and whose values are 10.255555 and 25.6999999
And we want to show them 10.2,25.6?
How can I do this with multibinding? Normally it is piece of cake with ValueConverter
Any help and ideas on this topic will be greately appreciated

Just set the StringFormat property on the MultiBinding; use placeholders ({0}, {1}...) for each binding in the multibinding, and include format specifiers if necessary (e.g. F1 for a decimal number with 1 decimal digit)
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0:F1}{1:F1}">
<Binding Path="A" />
<Binding Path="B" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
The {} part at the beginning is the format string is an escape sequence (otherwise the XAML parser would consider { to be the beginning of a markup extension)

If anyone is looking for "Time Formats" this is for 24hr Clock which is how I came to this post:
<TextBlock TextAlignment="Center">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0:HH:mm} - {1:HH:mm}">
<Binding Path="StartTime" />
<Binding Path="EndTime" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
The leading 0: and 1: are the reference to the Bindings
[0:hh:mm tt] to display AM/PM

To simplify you could use two TextBlock/Labels to display the values.
If you are using .Net4, you can bind in a Run Inline element of a TextBlock
<TextBlock>
<Run Text="{Binding A, StringFormat={}{0:F1}}"/>
<Run Text="{Binding B, StringFormat={}{0:F1}}"/>
</TextBlock>

Related

MultiBinding ComboBoxItem.Content

Hi I am trying to achieve a binding like this:
<ComboBoxItem Style="{StaticResource ComboBoxItemStyle2}">
<ComboBoxItem.Content>
<MultiBinding StringFormat=" {}{0} {1}">
<Binding Path="Value" Source="{StaticResource Name}" />
<Binding Path="Name" Source="{StaticResource Person}" />
</MultiBinding>
</ComboBoxItem.Content>
</ComboBoxItem>
Where "Name" is a localized string and "Value" is used to get it's localized string.
for some reason this doesn't seems to work. I am getting empty string.
This might help you: String format using MultiBinding?
Taken from that post:
You are trying to bind a string to an object. But StringFormat requires its target to be a string type. Try putting a TextBlock in your content and bind your data to it.
Also put "" around Name.
Following is the corrected code:
<ComboBoxItem Style="{StaticResource ComboBoxItemStyle2}">
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="Value" Source="{StaticResource Name}" />
<Binding Path="Name" Source="{StaticResource Person}" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</ComboBoxItem>
I need to fix two things:
Keep the content as TextBlock and do binding of text there.
Removed extra spacing from StringFormat i.e. " {}{0} {1}" ==> "{}{0} {1}".
You Can see this link i wish be helpful
https://social.msdn.microsoft.com/Forums/vstudio/en-US/32b81578-b201-4927-bdc2-ebb9a42ae303/comboboxdisplaymemberpath-and-multibinding

Wpf String.Format cause dependencyproperty.unsetvalue

This is the problem:
This is my XAML:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="My binding is: ({0})">
<Binding Path="FieldThatDoesntExistYet"></Binding>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
My datacontext is being loaded on run time, so It's end with the problem above.
Is there a simple XAML way to just show a default value ? empty or 0 will be great.
Adding a fallback value to your binding should do the trick. Whatever is between the '' will be what is displayed if the binding is invalid.
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="My binding is: ({0})">
<Binding Path="FieldThatDoesntExistYet" FallbackValue='0'></Binding>
</MultiBinding>
</TextBlock.Text>
</TextBlock>

Bind to several class properties

I have some class with properties firstName and lastName. I want bind TextBlock to concatanation of this two properties. I know that I can create third property that will be return concatanation of these properties. But I dont want to use this approach. Is it possible to Bind TextBlock to two properties. and also I dont want create composite userControl.
In .NET 3.5SP1, Microsoft added StringFormat to bindings. This makes it much easier. See Lester's blog post for an example. In your case:
<TextBox>
<TextBox.Text>
<MultiBinding StringFormat="{0} {1}">
<Binding Path="FirstName" />
<Binding Path="LastName"/>
</MultiBinding>
</TextBox.Text>
</TextBox>
or
<TextBox>
<TextBox.Text>
<MultiBinding StringFormat="{1}, {0}">
<Binding Path="FirstName" />
<Binding Path="LastName"/>
</MultiBinding>
</TextBox.Text>
</TextBox>
You could use multibinding, but I guess that you have to code your way out of the concatanation.
Here is an example: Multibinding
I'm not sure if it's possible to bind to two properties, but there is not reason you cannot create two TextBlocks right?
<TextBlock Text="{Binding firstName}"/> <TextBlock Text="{Binding lastName}"/>
use either MultiBinding or Converter (if complex operation is there)

How do you insert a binding into the middle of a sentence of a TextBlock in WPF?

I'm looking for something along these lines:
<TextBlock
Grid.Column="1"
Text="Welcome, {Binding UserName}!" />
This will of course actually display the text "{Binding UserName}" to the user rather than decode it, but I know you can do something like this with ASP.NET, so I'm hoping there's a way to get this to work in WPF.
I'm already aware that I could use an IValueConverter...I'm looking for something I can do purely in markup if possible.
EDIT:
Based on #Matt Hamilton's most excellent solution, I attempted to push the envelope and bind two values into the same TextBlock using a MultiBinding. Works like a charm:
<TextBlock
Style="{StaticResource TextBlock_ValueStyle}"
Grid.Column="1">
<TextBlock.Text>
<MultiBinding
StringFormat="{}Attempts: {0:G} of {1:G}">
<Binding
Path="AttemptNumber" />
<Binding
Path="AttemptCount" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
This produces: Attempts: 1 of 4 (assuming AttemptNumber = 1 and AttemptCount = 4).
I also found this link helpful for figuring out which formats to place after the colon:
http://msdn.microsoft.com/en-us/library/fbxft59x.aspx
You can use the StringFormat binding property in .NET 3.5 SP1:
<TextBlock Text="{Binding UserName,StringFormat='Welcome, \{0\}!'}" />
Note that you need to escape the curly braces in the string format with a backslash.
Update Yes, multiple values are also supported:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="Welcome, {0} {1}!">
<Binding Path="FirstName" />
<Binding Path="LastName" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
The best way of doing it is using the Runs...
<TextBlock>
<Run Text="Welcome"/>
<Run Text="{Binding UserName}"/>
<Run Text="!"/>
</TextBlock>
This is simplest way to mix text and controls
<TextBlock>Welcome, <TextBlock Text="{Binding UserName}"/>!</TextBlock>
you can inline styled buttons or other controls to.
So far I don't know of a solution which makes this possible in exactly the same way as you describe it. However, you can, as a workaround, use multiple text blocks to piece together your sentence:
<StackPanel Orientation="Horizontal">
<TextBlock Text="Welcome, "/>
<TextBlock Text="{Binding UserName}"/>
<TextBlock Text="!"/>
</StackPanel>
This is what I used so far and while cumbersome to type it seems to be the easiest solution. But as soon as you need Internationalization it's a no-go for obvious reasons.
Have a look at this library "WPFix". It allows the user to write lambda expressions in the XAML. I didn't use it in production code, only in demo code. I was able to take the width of a form, divide it by two, and bind the value to a control. Ordinarily, you would need to create a converter class, as you describe. This library may be the thing you are looking for:
http://www.fikrimvar.net/lestirelim/?p=15

WPF: Partial data binding in TextBlock

So here is my TextBlock:
<TextBlock Text="1 Projects / 1 Issues"></TextBlock>
Using data binding I want replace 1 and 2 with {Binding Path=OpenProjects} and {Binding Path=OpenIssues}. What is the best way to do this?
P.S. I am not married to TextBlock.
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} Projects / {1} Issues">
<Binding Path="OpenProjects"/>
<Binding Path="OpenIssues"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
You should look into string format

Resources