XAML text binding - wpf

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.

Related

Set/change text weight within the Text property of a TextBlock

I would like to be able to change the weight of text (e.g. change from Normal to Bold and back again) within the Text property string of a TextBlock (presumably using some control character set). Is this even possible?
TextBLock.Text creates a single Run, you set custom Inlines instead:
<TextBlock>
Text with <Bold>bold</Bold> within.
<TextBlock>
Obviously it no longer uses the Text property.
Are you talking about something like this?
<TextBlock>
<Run Text="Hey it's Normal Text"/>
<Run Text="Hey it's Bold Text" FontWeight="Bold"/>
<Run Text="Hey it's Colored Text" Foreground="Green"/>
</TextBlock>

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.

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

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.

WPF TextBlock binding with <LineBreak/>

I have a TextBlock binding as follows in my ControlTemplate.
<TextBlock Grid.Column="1" VerticalAlignment="Center"
FontSize="16" FontFamily="Arial" FontWeight="Bold"
Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=ButtonText}">
</TextBlock>
When I set ButtonText as follows with , it doesn't work. It doesn't display in separate line.
ButtonText="Change<LineBreak/> Casette"
How to fix this? Appreciate your help, please provide me with sample code.
A TextBlock displays the contents of its Inlines property. The Text property exists only as a convenience (though it's a significant one): if you set the Text property, the TextBlock will create a Run, set its content to the string you've provided, and save it in the Inlines collection.
When you set the content of a TextBlock element in XAML, the XamlReader populates the Inlines collection directly rather than through the Text property. It parses text nodes into Run objects, and elements as usual for XAML. So this:
<TextBlock>
Line1<LineBreak/>Line2
</TextBlock>
is treated as though it were actually this:
<TextBlock>
<Run>Line1</Run>
<LineBreak/>
<Run>Line2</Run>
</TextBlock>
Note, by the way, that if you try to set the Text property explicitly:
<TextBlock>
<TextBlock.Text>
Line1<LineBreak/>Line2
</TextBlock.Text>
</TextBlock>
you'll get an exception, because the XamlReader will try to create a LineBreak object, and the Text property can only contain a string.
Your binding isn't working the way you want it to because it's explicitly setting the Text property to a string. This doesn't get parsed as XAML (and good thing, too). And so what's displaying in the TextBlock is the content of that string.
So there are basically two ways to accomplish what you're trying to accomplish. In your case, you probably can just get away with embedding a newline into the string.
But this is trickier than it looks if you're doing it from XAML. Because XAML is XML, and XML does some funny things to whitespace. You're OK if you set it explicitly in an attribute using XML character entities, e.g.:
<TextBlock Text="Line 1
Line 2"/>
But that won't work if you do it this way:
<TextBlock>
<TextBlock.Text>
Line 1
Line 2
</TextBlock.Text>
</TextBlock>
because the XML parser normalizes whitespace in element content. That CR/LF pair gets turned into a single space, and that's what gets into the text property.
If you're using binding, you don't need to worry about any of this XML stuff (unless you're binding to the contents of an XML document!). You can just put \r\n into the property value.
The other way to do this is to directly populate the TextBlock's Inlines property. But you can't do this via binding, since Inlines isn't a dependency property - in fact, it's read-only, and you can only populate it by calling its Add or AddRange methods.
I used this code to obtain what you want. This is the XAML:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" VerticalAlignment="Center"
FontSize="16" FontFamily="Arial" FontWeight="Bold"
Text="{Binding Path=ButtonText}">
</TextBlock>
</Grid>
and this is the code behind. To make the example simplier, I don't create a ViewModel class:
public Window1()
{
InitializeComponent();
DataContext = this;
ButtonText = "Change\r\nCasette";
}
public string ButtonText
{
get { return (string)GetValue(ButtonTextProperty); }
set { SetValue(ButtonTextProperty, value); }
}
// Using a DependencyProperty as the backing store for ButtonText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ButtonTextProperty =
DependencyProperty.Register("ButtonText", typeof(string), typeof(Window1), new UIPropertyMetadata(""));

WPF Textblock, linebreak in Text attribute

Is there a way to have \n make a line break in a TextBlock?
<TextBlock Text="line1\nLine2" />
Or is there a better way to force a middle line break, inside the Text attribute?
<LineBreak />
This doesn't work for me, it needs to be the value of the Text attribute, because the text string is being set from an outside source.
I'm familiar with LineBreak but it's not the answer I'm looking for.
Try this:
<TextBlock>
line1
<LineBreak />
line2
</TextBlock>
I know this is ressurecting an old question, but I had the same problem. The solution for me was to use HTML encoded line feeds (&#10;).
Line1&#10;Line2
Looks like
Line1
Line2
For more of the HTML encoded characters check out w3schools
The easiest way is
<TextBlock> blabla <LineBreak /> coucou <LineBreak /> coucou 2 </TextBlock>
So you just write XAML code, and the <LineBreak /> has exactly the same meaning the in HTML or the "\n" in C#.
<LineBreak/>
http://www.longhorncorner.com/UploadFile/mahesh/XamlLineBreak06092005152257PM/XamlLineBreak.aspx
How about breaking the line into two tags?
<StackPanel>
<TextBlock Text="Line1" />
<TextBlock Text="Line2" />
</StackPanel>
<LineBreak/> will not work if it is inside a collection such as Grid or StackPanel.
In such cases the following would work as shown:
Correct way to use it may be the following :
<TextBlock>
<Span>text1</Span>
<LineBreak/>
<Span>text2</Span>
</TextBlock>
The Best way that worked for me for multiple lines in the same Textblock is:
<TextBlock>
text1
<LineBreak/>
text2
</TextBlock>
Make sure to not use TextWrapping="Wrap". Use TextWrapping="NoWrap" or use nothing.
<HyperlinkButton
Content="Apply and restart this pplication!
Note that modifying these settings requires the application to be restarted." />
CRLF simple way = !
!
- Work on all wpf, xaml, silverlight controls like TextBlock, HyperlinkText and more
If you are binding TextBlock's Text, none of the other answers work. Simply add '\n' to the binding text to where you want to break.
this &#10; did not work for me, when I used binding. But this works:
$"first line {Environment.NewLine} second line"
I'm late to the party but ..
this is more or less how I did it ,(mind my ItemSources are plain strings, not formatted , and I didn't need to 'convertBack' anything)
public class SpaceToLineBreakConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (!String.IsNullOrEmpty(value as string))
? new Regex(#"\s").Replace(value as string, "\n")
: value;
}
public object ConvertBack(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
This also works fine:
<TextBlock>
<Run Text="My nice text"/>
<LineBreak/>
<LineBreak/>
<Run Text="After some linebreaks, I'm back!"/>
</TextBlock>
I was having a similar problem and wanted to bind a String of xaml markup to a TextBlock. Essentialy storing the declarative markup inside a TextBlock in a string for later use.
This is how I did: I subclassed the TextBlock to make the InlineCollection bindable and wrote a Converter between the string and an InlineCollection(or actually a generic list of Inlines.)
just use the AccessText control. you can use it like a label and you have the property TextWrapping="WrapWithOverflow"
eg.
Mine is like that and it's working fine. Also, you don't have any problems on changing the text dinamically.
This also works fine.
Using this method we can modify the text properties in each line as we required.
<TextBlock>
<StackPanel>
<TextBlock FontSize="12" FontWeight="Bold" >My Text One</TextBlock>
<TextBlock FontFamily="Times New Roman" FontStyle="Italic">
- My Text Two
</TextBlock>
</StackPanel>
</TextBlock>

Resources