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>
Related
Trying for a simple thing. I want TextBlock text to be updated to what TextBox's text value is. However, I want it to happen only on LostFocus. Currently below code updates a TextBlock as user is typing into a TextBox. How do we achieve that?
<StackPanel>
<TextBox x:Name="txtQty" />
<TextBlock Text="{Binding ElementName=txtQty, Path=Text}" />
</StackPanel>
I explored the UpdateSourceTrigger property on textbox with LostFocus, but it won't work as that controls how the source should be updated, whereas here I need how the destination updates.
I prefer to have a XAML only solution.
XAML is a markup language.
The straight-forward way to to this would be to bind the TextBox and the TextBlock to the same view model source property. The source property will be set when the TextBox loses focus and then the TextBlock will then be updated provided that the view model class implements the INotifyPropertyChanged interface as expected.
You could of course also handle the LostKeyboardFocus event for the TextBox and set the Text property of the TextBlock programmatically in the code-behind of the view. This approach is not any worse than trying to implement some logic in the XAML markup of the very same view. Just because you possibly can do something in pure XAML, it doesn't mean that you always should. A programming language such as C# usually does a better job implementing some logic.
As others already said, the best way would be to bind the TextBlock and the TextBox to the same viewmodel property.
If you want to do it only with XAML code you could try it from the other side and bind your TextBox to the TextBlock.
Like this:
<StackPanel>
<TextBox Text="{Binding ElementName=txtQty, Path=Text, UpdateSourceTrigger=LostFocus, Mode=OneWayToSource}" />
<TextBlock x:Name="txtQty" />
</StackPanel>
I defined a TextBlock in xaml with binding:
<TextBlock Text="{Binding ElementName=MyClass, Path=MyStringProperty}"/>
When I set MyStringProperty to , for example , <b>Hello, World!</b> it shows it as plain text. Is there a way to tell the control to make the Hello, World! string bold?
You can't do this with a TextBlock like that.
You need to bind the FontWeight property of the text block to a variable that holds the bold/not bold value.
If the value is a boolean you need to write a converter to map the boolean value to the font weight property.
If you want to change the boldness (or any other property) of the text at runtime based on what the user types in then you need to be looking at using a RichTextBox.
Use the Inlines property:
<TextBlock Text="{Binding ElementName=MyClass, Path=MyStringProperty}">
<Run FontWeight="Bold" Text="{Binding BoldText}" />
</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 can I bind a property to the Run tag in a Textblock control in WPF. And I am using MVVM.
you did not post some code, but this works
<Grid>
<TextBlock>
<Run Text="{Binding Path=MyViewmodelProperty}"/>
</TextBlock>
</Grid>
Starting from .NET 4.0, you can bind to the Text property of a Run. Before that, it's not possible. Can't you just bind to the TextBlock.Text property?
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