Strange MultiBinding StringFormat issue - wpf

I have this XAML
<MultiBinding StringFormat=" {0}{1}/{2}">
<Binding Path="Text" ElementName="tbxAuthHost" />
<Binding Path="Text" ElementName="tbxAuthWebsiteName" />
<Binding Path="Text" ElementName="tbxAuthServicesAddress" />
</MultiBinding>
When I try change " {0}{1}/{2}" into "{0}{1}/{2}" so no leading space there and then Visual Studio gives this error:
Error 3 The text '{1}/{2}' is not allowed after the closing '}' of a MarkupExtension expression. Line 116 Position 56.
How I can fix this issue?

You can fix this by putting {} at the front of the string format.
StringFormat="{}{0}{1}/{2}"
The MSDN Page does a particularly bad job of explaining the format.
If you look at the page on the escape sequence it explains that an opening curly bracket at the beginning denotes a markup extension (e.g. Binding), and {0}{1}/{2} is not a valid markup extension. It doesn't explain that not having it as the first character also works.

Related

How to supply a string literal value as a binding in WPF

EDIT:
My former question also referred to commands, but as pointed out in a comment below, it was unnecessary and added noise.
This is more a XAML syntax question, so it is probably trivial.
I would like to know how to pass a string literal as a value for a binding in WPF.
If the value is already known from the context in XAML, may its value simply be directly assigned to the binding, instead of using paths and other means?
If so, what would the syntax be in that case?
<MultiBinding.Bindings>
<!-- First binding, a textbox -->
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type TextBox}}"/>
<!-- Second binding, I want to pass a string as is, for instance, "Description" -->
<!-- The proper syntax for the line below is what I am after -->
<Binding Value="Description"/>
</MultiBinding.Bindings>
It's
<Binding Source="Description"/>
Source can be any type, so in attribute syntax that is interpreted as a string, if no Path is specified a binding's value is the source.
Also that is a multi-binding, i would not talk about command parameters as that is irrelevant to the matter...

Using String from a dictionary in a ConverterParameter

I'm trying to use a String from a dictionary:
<?xml version="1.0" encoding="utf-8" ?>
<Dictionary EnglishName="English" CultureName="English" Culture="en-US">
...
<Value Id="ButtonSuppressFieldInformation"
ToolTip="Remove field" Name="Remove field number "/>
...
</Dictionary>
In this ConverterParamter to enable multiple langages support:
<Button>
...
<AutomationProperties.Name>
<MultiBinding
Converter="{StaticResource IndexedForAutomationId}"
ConverterParameter="{loc:Translate
Uid=ButtonSuppressFieldInformation, Default=Delete field}">
<Binding RelativeSource="{RelativeSource Self}" />
<Binding ElementName="MyContactDirectoryView"
Path="ListConditionToSearch" />
</MultiBinding >
</AutomationProperties.Name>
</Button>
But the only thing shown is the number (IndexedForAutomationId), the string does not appear.
Using a string instead of "{loc:Translate Uid=ButtonSuppressFieldInformation, Default=Delete field}" works:
<MultiBinding Converter="{StaticResource IndexedForAutomationId}"
ConverterParameter="Delete field">
Displays Delete field 0.
What is the way to use loc:Translate as a ConverterParameter?
This issue could be due to a lot of things and some more code would really help here. I would start, however, with a breakpoint on the Convert() method of the IndexedForAutomationId converter to 1) check if you get the values your are expecting from the inner bindings and 2) check if the converter itself is returning the right string from the dictionary.
Please make sure to review these guidelines about how to debug WPF bindings as well.

Stringformat concatenates databinding and resource's value

I want to concatenate in my window title a property from my viewmodel and a value that cames from a resources file.
This is what I have working without the string from resources:
Title="Binding Path=Description, StringFormat=Building: {0}}"
Now I want to remove the "Building" string and put a value from a resource like I use on other places:
xmlns:res="clr-namespace:Project.View.Resources"
{res:Strings.TitleDescription}
How can I define both? Can I define like a {1} parameter?
I've seen the MultiBinding answer in several places now, and it is almost never necessary to use it. You can define your resource as the string format instead, and as long as there is only one string format argument, no MultiBinding is required. Makes the code a lot more succinct:
<TextBlock Text="{Binding Description, StringFormat={x:Static res:Strings.TitleDesc}}" />
And the TitleDesc resource is obviously "Building: {0}".
Yes, you can. Simply use a MultiBinding.
The MSDN article on StringFormat has an example.
In your case, the code would look something like this:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Source="{x:Static res:Strings.TitleDescription}"/>
<Binding Path="Description"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>

MultiBinding not working but corresponding Binding does work

I have the following code:
<local:StaffAtMeetingEditor DataContext="{Binding Meeting}" Grid.Row="1">
<local:StaffAtMeetingEditor.InEditMode>
<MultiBinding Converter="{StaticResource myMeetingLogEditableMultiConverter}">
<Binding Path="ParentSI.ItemInEditMode"/>
</MultiBinding>
</local:StaffAtMeetingEditor.InEditMode>
</local:StaffAtMeetingEditor>
The setup is that the containing control's datatype is "SIP_ServiceItem". This class has a property called "Meeting" (which is set as the DataContext for the local:StaffAtMeetingEditor control), which itself has a member called "ParentSI", pointing back to the parent SIP_ServiceItem object.
The issue is, that if I pass this through as a single binding (i.e. remove the start and end MultiBinding tags from the code above, leaving just the Binding), it works just fine. But when I make it a MultiBinding (I wish to add some other Bindings to this shortly), and try to pass the bound value through to myMeetingLogEditableMultiConverter, the values(0) parameter, which should correspond to the boolean ParentSI.ItemInEditMode is actually an MS.Internal.NamedObject, implying there's a null reference somewhere. Furthermore, the ParentSI property is never being evaluated, so something is going completely wrong. I am at a loss to know the difference between the single binding and multi binding cases.
Thanks.
I know this is a bit old, and you have likely figured this out by now, but I came across this as I had a similar problem and thought I'd share the solution: I had the same problem and have added the attributes ElementName and Mode as below:
<Binding Path="CurrentProvider.IsBusy" ElementName="parent" Mode="OneWay" />
Hope this helps someone, even if the OP has fixed their issue.
May be you should try to add any temporary unused bound value. For instance:
<local:StaffAtMeetingEditor DataContext="{Binding Meeting}" Grid.Row="1">
<local:StaffAtMeetingEditor.InEditMode>
<MultiBinding Converter="{StaticResource myMeetingLogEditableMultiConverter}">
<Binding Path="ParentSI.ItemInEditMode"/>
<Binding Path="ParentSI"/>
</MultiBinding>
</local:StaffAtMeetingEditor.InEditMode>
</local:StaffAtMeetingEditor>
If it doesn't work then your implementation is wrong, another case - it's MultiBinding limitations.

WPF Multibinding string format date

I'm trying to combine 2 fields of information in my grid by using a Multibinding, the multibinding is working fine but I'm having problems when I try to start formating 1 of the fields which is a date in this binding.
The 2 fields are Users Initials i.e. EGJ and the entry date hoping to achieve a combined field looking like "EGJ - 01/01/2011"
Below is where I'm with my existing XAML
<tk:DataGridTextColumn.Binding>
<MultiBinding StringFormat=" {0} - {}{1:dd/MM/yyyy}">
<Binding Path="UserInitials" />
<Binding Path="EntryDate" />
</MultiBinding>
</tk:DataGridTextColumn.Binding>
Any help or pointers are most appreciated
Couldn't see the wood for the trees
Simply removing the empty braces solved my problem.
<tk:DataGridTextColumn.Binding>
<MultiBinding StringFormat=" {0} - {1:dd/MM/yyyy}">
<Binding Path="UserInitials" />
<Binding Path="EntryDate" />
</MultiBinding>
</tk:DataGridTextColumn.Binding>
Thanks to everyone who took the time to look.
Unless you intend to have a leading space in the formatted value you should use this binding instead:
<tk:DataGridTextColumn.Binding>
<MultiBinding StringFormat="{}{0} - {1:dd/MM/yyyy}">
<Binding Path="UserInitials" />
<Binding Path="EntryDate" />
</MultiBinding>
</tk:DataGridTextColumn.Binding>
If the StringFormat starts with a left brace { the XAML parser require you to escape it using a pair of braces {}. Otherwise the parser gets confused because braces also are used in the syntax of markup extensions.
Details are found in the XAML documentation for {} Escape Sequence / Markup Extension.
Perhaps you had the escape sequence correctly placed in the format string initially and the moved things around resulting in the empty pair of braces at the wrong place?

Resources