I want to know the code equivalent of the part that is inside the TextBlock:
<TextBlock>
Hello
<Run Background="Red">S</Run>
<Run Background="Blue">O</Run>
</TextBlock>
The reason is that I have a converter that returns the TextBox content, but I'm not sure what type to return from the converter. I tried some collection types, that contain the string and the 2 Run instances but that wouldnt work.
Also I noticed that the following wouldnt work:
<TextBlock>
<TextBlock.Text> <--- Added this
Hello
<Run Background="Red">S</Run>
<Run Background="Blue">O</Run>
</TextBlock.Text>
</TextBlock>
So my second question is to which property do I have to bind my converter result?
Firstly, you can add Run blocks via the InLines property, e.g.
TextBlock txtBlock = new TextBlock();
txtBlock.Inlines.Add(new Run { Text = "S", Background = Brushes.Red });
txtBlock.Inlines.Add(new Run { Text = "O", Background = Brushes.Blue });
Secondly, you cannot add via "TextBlock.Text" as this is expecting a string, not a collection of Runs.
Try this:
<Label>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Hello"/>
<TextBlock Background="Red" Text="S"/>
<TextBlock Background="Blue" Text="O"/>
</StackPanel>
</Label>
Add your converter to the binding of each textblocks.I think its more flexible than using the Run
Related
I have a User control and I bind the tooltip of that control into some object's property
<usercontrols:ucButton x:Name="xSaveCurrentBtn" ButtonType="ImageButton" ButtonFontImageSize="16" ButtonImageWidth="18" ButtonImageHeight="18" ButtonImageType="Save" Click="xSaveSelectedButton_Click" ButtonStyle="{StaticResource $ImageButtonStyle_Menu}" DockPanel.Dock="Right" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,0,0">
<usercontrols:ucButton.ToolTip>
<ToolTip Content="{Binding ItemName, Mode=OneWay}" ContentStringFormat="Save {0}"/>
</usercontrols:ucButton.ToolTip>
</usercontrols:ucButton>
from the code I set the data context of the ucButton to be my object:
xSaveCurrentBtn.DataContext = WorkSpace.Instance.CurrentSelectedItem;
sometimes the CurrentSelectedItem is null, and if this is the case I want the tooltip to display "No Item Selected"
I tried doing this:
xSaveCurrentBtn.Tooltip = "No Item Selected";
but when the CurrentSelectedItem isn't null and I reset the xSaveBtn.DataContext to that object, I am still seeing the No Item Selected tooltip as if my WPF tooltip section was overriden and its no longer binding into the datacontext ItemName Property
You are trying to set a property to two values at the same time. It's impossible.
What you are doing in XAML is equivalent to:
xSaveCurrentBtn.Tooltip = new ToolTip() {.....};
When you setting a string value to the same property, the previous value is lost. And it is not possible to restore it if you do not save it first.
You might want to assign a value in case of a binding error:
<ToolTip Content="{Binding ItemName,
Mode=OneWay,
FallbackValue='No Item Selected'}"
ContentStringFormat="Save {0}"/>
how can I bind the data context to update to be the new CurrentSelectedItem without explicitly setting it?
Assuming that «WorkSpace.Instance» is an immutable property that returns an instance of «WorkSpace» and «CurrentSelectedItem» is a property with an «INotifyPropertyChanged.PropertyChanged» notification, then you can do this:
<usercontrols:ucButton DataContext="{Binding CurrentSelectedItem, Source={x:Static viewmodels:WorkSpace.Instance}}" ...>
The «viewmodels» prefix depends on the assembly and namespace in which the «WorkSpace» class is declared.
you can use ContentTemplate with TextBlock, which will either use StringFormat, or TargetNullValue depending on ItemName being null:
<usercontrols:ucButton.ToolTip>
<ToolTip Content="{Binding ItemName}">
<ToolTip.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding StringFormat='Save {0}',
TargetNullValue='No Item Selected'}"/>
</DataTemplate>
</ToolTip.ContentTemplate>
</ToolTip>
</usercontrols:ucButton.ToolTip>
or if you bind Tooltip.Content differently:
<usercontrols:ucButton.ToolTip>
<ToolTip Content="{Binding}">
<ToolTip.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=ItemName,
StringFormat='Save {0}',
FallbackValue='No Item Selected'}"/>
</DataTemplate>
</ToolTip.ContentTemplate>
</ToolTip>
</usercontrols:ucButton.ToolTip>
I am following MVVM pattern for my project and wanted to bind a string property to a TextBlock Text property.I want some of the words in the string property hace different color like
User has completed the Survey
I am not getting how to achieve this multicolored string in viewmodel.
I wanted this should happen in viewmodel because this message is dependent on conditions.
You could use the Run property
non mvvm
<Run Foreground="Blue">User</Run>
<Run Foreground="Black">has completed the</Run>
<Run Foreground="Blue">Survey</Run>
</TextBlock>
or Mvvm you could have your view model format the strings and then just bind to the relevant properties
<TextBlock>
<Run Text={Binding your_mvvm_property}" Foreground="{StaticResource your_style"/>
<Run Text={Binding your_mvvm_property2}" Foreground="{StaticResource your_style2"/>
</TextBlock>
I have a WPF 4 application that contains a TextBlock which has a one-way binding to an integer value (in this case, a temperature in degrees Celsius). The XAML looks like this:
<TextBlock x:Name="textBlockTemperature">
<Run Text="{Binding CelsiusTemp, Mode=OneWay}"/></TextBlock>
This works fine for displaying the actual temperature value but I'd like to format this value so it includes °C instead of just the number (30°C instead of just 30). I've been reading about StringFormat and I've seen several generic examples like this:
// format the bound value as a currency
<TextBlock Text="{Binding Amount, StringFormat={}{0:C}}" />
and
// preface the bound value with a string and format it as a currency
<TextBlock Text="{Binding Amount, StringFormat=Amount: {0:C}}"/>
Unfortunately, none of the examples I've seen have appended a string to the bound value as I'm trying to do. I'm sure it's got to be something simple but I'm not having any luck finding it. Can anyone explain to me how to do that?
Your first example is effectively what you need:
<TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0}°C}" />
Here's an alternative that works well for readability if you have the Binding in the middle of the string or multiple bindings:
<TextBlock>
<Run Text="Temperature is "/>
<Run Text="{Binding CelsiusTemp}"/>
<Run Text="°C"/>
</TextBlock>
<!-- displays: 0°C (32°F)-->
<TextBlock>
<Run Text="{Binding CelsiusTemp}"/>
<Run Text="°C"/>
<Run Text=" ("/>
<Run Text="{Binding Fahrenheit}"/>
<Run Text="°F)"/>
</TextBlock>
Please note that using StringFormat in Bindings only seems to work for "text" properties. Using this for Label.Content will not work
In xaml
<TextBlock Text="{Binding CelsiusTemp}" />
In ViewModel, this way setting the value also works:
public string CelsiusTemp
{
get { return string.Format("{0}°C", _CelsiusTemp); }
set
{
value = value.Replace("°C", "");
_CelsiusTemp = value;
}
}
How do I achieve formatting of a text inside a TextBlock control in my WPF application?
e.g.: I would like to have certain words in bold, others in italic, and some in different colors, like this example:
The reason behind my question is this actual problem:
lblcolorfrom.Content = "Colour From: " + colourChange.ElementAt(3).Value.ToUpper();
I would like the second part of the string to be bold, and I know that I could use two controls (Labels, TextBlocks, etc.) but I'd rather not, due the vast amount of controls already in use.
You need to use Inlines:
<TextBlock.Inlines>
<Run FontWeight="Bold" FontSize="14" Text="This is WPF TextBlock Example. " />
<Run FontStyle="Italic" Foreground="Red" Text="This is red text. " />
</TextBlock.Inlines>
With binding:
<TextBlock.Inlines>
<Run FontWeight="Bold" FontSize="14" Text="{Binding BoldText}" />
<Run FontStyle="Italic" Foreground="Red" Text="{Binding ItalicText}" />
</TextBlock.Inlines>
You can also bind the other properties:
<TextBlock.Inlines>
<Run FontWeight="{Binding Weight}"
FontSize="{Binding Size}"
Text="{Binding LineOne}" />
<Run FontStyle="{Binding Style}"
Foreground="Binding Colour}"
Text="{Binding LineTwo}" />
</TextBlock.Inlines>
You can bind through converters if you have bold as a boolean (say).
You can do this in XAML easily enough:
<TextBlock>
Hello <Bold>my</Bold> faithful <Underline>computer</Underline>.<Italic>You rock!</Italic>
</TextBlock>
There are various Inline elements that can help you, for the simplest formatting options you can use Bold, Italic and Underline:
<TextBlock>
Sample text with <Bold>bold</Bold>, <Italic>italic</Italic> and <Underline>underlined</Underline> words.
</TextBlock>
I think it is worth noting, that those elements are in fact just shorthands for Span elements with various properties set (i.e.: for Bold, the FontWeight property is set to FontWeights.Bold).
This brings us to our next option: the aforementioned Span element.
You can achieve the same effects with this element as above, but you are granted even more possibilities; you can set (among others) the Foreground or the Background properties:
<TextBlock>
Sample text with <Span FontWeight="Bold">bold</Span>, <Span FontStyle="Italic">italic</Span> and <Span TextDecorations="Underline">underlined</Span> words. <Span Foreground="Blue">Coloring</Span> <Span Foreground="Red">is</Span> <Span Background="Cyan">also</Span> <Span Foreground="Silver">possible</Span>.
</TextBlock>
The Span element may also contain other elements like this:
<TextBlock>
<Span FontStyle="Italic">Italic <Span Background="Yellow">text</Span> with some <Span Foreground="Blue">coloring</Span>.</Span>
</TextBlock>
There is another element, which is quite similar to Span, it is called Run. The Run cannot contain other inline elements while the Span can, but you can easily bind a variable to the Run's Text property:
<TextBlock>
Username: <Run FontWeight="Bold" Text="{Binding UserName}"/>
</TextBlock>
Also, you can do the whole formatting from code-behind if you prefer:
TextBlock tb = new TextBlock();
tb.Inlines.Add("Sample text with ");
tb.Inlines.Add(new Run("bold") { FontWeight = FontWeights.Bold });
tb.Inlines.Add(", ");
tb.Inlines.Add(new Run("italic ") { FontStyle = FontStyles.Italic });
tb.Inlines.Add("and ");
tb.Inlines.Add(new Run("underlined") { TextDecorations = TextDecorations.Underline });
tb.Inlines.Add("words.");
Check out this example from Charles Petzolds Bool Application = Code + markup
//----------------------------------------------
// FormatTheText.cs (c) 2006 by Charles Petzold
//----------------------------------------------
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Documents;
namespace Petzold.FormatTheText
{
class FormatTheText : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new FormatTheText());
}
public FormatTheText()
{
Title = "Format the Text";
TextBlock txt = new TextBlock();
txt.FontSize = 32; // 24 points
txt.Inlines.Add("This is some ");
txt.Inlines.Add(new Italic(new Run("italic")));
txt.Inlines.Add(" text, and this is some ");
txt.Inlines.Add(new Bold(new Run("bold")));
txt.Inlines.Add(" text, and let's cap it off with some ");
txt.Inlines.Add(new Bold(new Italic (new Run("bold italic"))));
txt.Inlines.Add(" text.");
txt.TextWrapping = TextWrapping.Wrap;
Content = txt;
}
}
}
a good site, with good explanations:
http://www.wpf-tutorial.com/basic-controls/the-textblock-control-inline-formatting/
here the author gives you good examples for what you are looking for! Overal the site is great for research material plus it covers a great deal of options you have in WPF
Edit
There are different methods to format the text. for a basic formatting (the easiest in my opinion):
<TextBlock Margin="10" TextWrapping="Wrap">
TextBlock with <Bold>bold</Bold>, <Italic>italic</Italic> and <Underline>underlined</Underline> text.
</TextBlock>
Example 1 shows basic formatting with Bold Itallic and underscored text.
Following includes the SPAN method, with this you van highlight text:
<TextBlock Margin="10" TextWrapping="Wrap">
This <Span FontWeight="Bold">is</Span> a
<Span Background="Silver" Foreground="Maroon">TextBlock</Span>
with <Span TextDecorations="Underline">several</Span>
<Span FontStyle="Italic">Span</Span> elements,
<Span Foreground="Blue">
using a <Bold>variety</Bold> of <Italic>styles</Italic>
</Span>.
</TextBlock>
Example 2 shows the span function and the different possibilities with it.
For a detailed explanation check the site!
Examples
This is my solution....
<TextBlock TextWrapping="Wrap" Style="{DynamicResource InstructionStyle}">
<Run Text="This wizard will take you through the purge process in the correct order." FontWeight="Bold"></Run>
<LineBreak></LineBreak>
<Run Text="To Begin, select" FontStyle="Italic"></Run>
<Run x:Name="InstructionSection" Text="'REPLACED AT RUNTIME'" FontWeight="Bold"></Run>
<Run Text="from the menu." FontStyle="Italic"></Run>
</TextBlock>
I am learning... so if anyone has thaughts on the above solution please share! :)
private TextBlock _caption = new TextBlock();
public TextBlock Caption
{
get { return _caption; }
set { _caption = value; }
}
<l:CustomPanel>
<l:CustomPanel.Caption Text="Caption text" FontSize="18" Foreground="White" />
</l:CustomPanel>
Gives me the following error:
Cannot set properties on property elements.
If I use:
<l:CustomPanel>
<l:CustomPanel.Caption>
<TextBlock Text="Caption text" FontSize="18" Foreground="White" />
</l:CustomPanel.Caption>
</l:CustomPanel>
My TextBlock shows up fine but it's nested inside another TextBlock like so, it even seems to add itself outside of the Caption property:
<l:CustomPanel>
<l:CustomPanel.Caption>
<TextBlock>
<InlineUIContainer>
<TextBlock Text="Caption text" FontSize="18" Foreground="White" />
</InlineUIContainer>
</TextBlock>
</l:CustomPanel.Caption>
<TextBlock>
<InlineUIContainer>
<TextBlock Text="Caption text" FontSize="18" Foreground="White" />
</InlineUIContainer>
</TextBlock>
</l:CustomPanel>
As you might have already guessed, what i'd like my code to do is to set my Caption property from XAML on a custom panel, if this is possible.
I've also tried the same code with a DependencyProperty to no avail.
So, anyone that can help me with this problem?
I can explain what is going wrong and how to fix it.
First,
<l:CustomPanel>
<l:CustomPanel.Caption Text="Caption text" FontSize="18" Foreground="White" />
is a simple syntax error. The <l:CustomPanel.Caption> syntax does not accept XML attributes - the property value must be within the element.
This is proper property element syntax:
<l:CustomPanel>
<l:CustomPanel.Caption>
<TextBlock Text="Caption text" FontSize="18" Foreground="White" />
</l:CustomPanel.Caption>
</l:CustomPanel>
but:
Property element syntax works only with DependencyProperties (so it didn't work with your CLR property) and
Property element syntax always honors the ContentPropertyAttribute of the property type
Since TextBlock has a [ContentPropertyAttribute("Inlines")], the property element syntax is trying to add the TextBlock to the Inlines collection.
The solution is simple: Declare your property as a DependencyProperty of type UIElement instead of type TextBlock. This has the additional advantage of not restricting the display of content to just a TextBlock. If you really do want to restrict it to just a TextBlock, you can use a validation callback.
public UIElement Content { get { ...
public static readonly DependencyProperty ContentProperty = ...
Just got a non-ideal workaround from a colleague of mine. It involves declaring the Caption property as a resource like:
<Page.Resources>
<TextBlock x:Key="test" Text="Caption text" FontSize="18" Foreground="White" />
</Page.Resources>
<l:CustomPanel Caption="{StaticResource test}" />
I'd still like to know why I can't use the two previous options, so if anyone knows please answer. :)
It seems that you can get this error (in Silverlight 4 and 5 at least) if you specify a namespace on the element. For example:
<Path>
<MapLayer.Position xmlns="clr-namespace:Microsoft.Maps.MapControl">
...
In this case MapLayer.Position is an attached property. It seems that the Silverlight parser requires the namespace to be defined using a prefix:
<Path xmlns:map="clr-namespace:Microsoft.Maps.MapControl">
<map:MapLayer.Position>
...