How to bind to a dictionary entry with key ending in '{'? - wpf

I want to bind to a value in a dictionary property of an object. The dictionary key of this value is a string ending in '{'. How do I express this in XAML?
I presumably need to escape this character somehow.
Example XAML that doesn't work:
<TextBlock Text="{Binding Attribs[test{]}" />
Here Attribs is a property on the datacontext object of type IDictionary<string, object>

This XAML works, by avoiding using a binding expression and instead using a Binding element:
<TextBlock>
<TextBlock.Text><Binding Path="Attribs[test{]"/></TextBlock.Text>
</TextBlock>

I just have tested the following XAML fragment, and it seems to work fine:
<TextBlock Text="{Binding Attribs[test\{]}"/>
The \ escape character is explained in this article.

Related

Binding to dictionary using enum as key

I came across a problem with binding to dictonary property using enum as key in xaml file.
I have a ViewModel with property
public Dictionary<EColor, MyDataStatus> StatusByColor {get; set;}
Where EColor is as enum and MyDataStatus is my own class with property Value.
In a view I'm trying to create a binding
<TextBlock Text="{Binding StatusByColor[enum:EColor.eRed].Value}"/>
and I get an binding error
BindingExpression path error: '[]' property not found on 'object' ''Dictionary`2 .....
However if I enter a digit (instead of using enum) like this:
<TextBlock Text="{Binding StatusByColor[0].Value}"/>
It works perfectly fine
I thought it may be a problem with "including" enum in xaml (it is defined in other assembly) but a few lines below i can use it as CommandParameter like this.
Text="{Binding Path=StatusByColor, Mode=OneWay,
Converter={StaticResource statusByColorToDayElapsedConverter},
ConverterParameter={x:Static enum:EPaintColor.eRed}}"
And in this scenario (with converterParameter) even IntelliSense suggests enum's values.
This is how I "include" enum in xaml:
"xmlns:enum="clr-namespace:CommonTypes.Enums;assembly=CommonTypes""
Firstly,Give my answer,and I have verified it.
<TextBlock Text="{Binding StatusByColor[eRed].Value}"/>
I tried your code with a sample and get the same result as you mentioned.
But when I try this code.
<TextBlock Text="{Binding StatusByColor[0].Value}"/>
I changed the index from 0 to 999.I got an exception
"System.Collections.Generic.KeyNotFoundException"
So I confirm that there is a type casting from Int to Enum.
However,only Int can be converted? How about string?
Yes!String also worked.
Refer:
WPF Binding to items within a dictionary by key?

Binding Source vs x:Static

in WPF one can bind to static properties. Now I know 2 ways of doing this:
Content="{x:Static stat:Statics.CurrentUser}"
Or:
Content="{Binding Source={x:Static stat:Statics.CurrentUser}}"
Are there any differences between these 2 methods?
Main difference in this case is that x:Static does not perform additional conversion
From x:Static Markup Extension
Use caution when you make x:Static references that are not directly the type of a property's value. In the XAML processing sequence, provided values from a markup extension do not invoke additional value conversion. This is true even if your x:Static reference creates a text string, and a value conversion for attribute values based on text string typically occurs either for that specific member or for any member values of the return type.
So lets say you do
<TextBlock Text="{x:Static SystemColors.ActiveBorderBrush}"/>
this will cause runtime error:
'#FFB4B4B4' is not a valid value for property 'Text'.
because SolidColorBrush is not String whilst
<TextBlock Text="{Binding Source={x:Static SystemColors.ActiveBorderBrush}}"/>
will work fine and display #FFB4B4B4 because it will perform ToString() conversion. Also without Binding you are not able to access instance properties of static object so for example you would not be able to get Color property of that brush
<TextBlock Text="{Binding Source={x:Static SystemColors.ActiveBorderBrush}, Path=Color}"/>

Bind TextBlock text when it is more then a simple string

I have a textblock and I would like to bind its content to a property in my viewmodel. This is fine if the content is a simple string. But it's no so fine if I want to format the content and use or tags... In this case I cannot bind a string: the textblock would simply display a string like this "Hallo".
Any ideas ? Thanks
if you have a property of some type - you can create a datatemplate for this type
<DataTemplate DataType="{x:Type local:MySomeType}">
<!--your visual presentation goes here-->
</DataTemplate>
now you can simply use a ContentPresenter to show your property
<ContentPresenter Content="{Binding MySomeTypeProperty}"/>
See what the StringFormat property can do for you. If that is not sufficient, you might want to write a binding converter.
Something like this:
<Textblock content="{Binding MyProperty, StringFormat={}Hello {1}}" />
Just got to play with the string format.

Assigning to an attached property using a child element

Regular (not attached) properties in XAML can be assigned either as an attribute or as child element.
Example:
<TextBlock Foreground="Blue">Some text</TextBlock>
Or:
<TextBlock>
<TextBlock.Foreground>
<SolidColorBrush>Blue</SolidColorBrush>
</TextBlock.Foreground>
Some text
</TextBlock>
Since attached properties are usually simple, I only see examples of assigning to them using an attribute, example:
<TextBlock Grid.Row="1">Some text</TextBlock>
But is it possible to assign to an attached property using a child element?
I have a custom control that has an attached property of a complex (class) type. Since I can't specify the value in an attribute, I'm not sure how to assign to it from XAML.
This feature is called the property element syntax and yes, you can set attached properties using the element attribute syntax:
<TextBlock>
<Grid.Column>1</Grid.Column>
ABC
</TextBlock>

XAML text binding

I would bind a string property to text property like this: Text="{Binding propertyName}.
I also want to append a hardcoded string to this like Text="{Binding propertyName} appendedName. How to do this?
Text="{Binding propertyName,StringFormat='Your property is: {}{0}'}"
You could use Run Text:
<TextBlock>
<Run Text="{Binding YourBinding}"/>
<Run Text="Suffix"/>
</TextBlock>
If you want to use it like this several times I would recommend a TemplatedControl where you have a Suffix DependencyProperty and a Text DependencyProperty.
You should create new property that returns text + appendedName.
Another way is to use several text blocks.

Resources