Concat content of ContentPresenter

420 Views Asked by At

Trying to set the text inside progressBar and i am getting properly with Setters. but i have to concat this value with:

{TemplateBinding Value}+"% Completed 

How do i concat with some other Text.

Code where text printed inside progressbar:

 <Border x:Name="whiteBorder" >
       <ContentPresenter   x:Name="perHolder" Content="{TemplateBinding Value}" VerticalAlignment="Center" HorizontalAlignment="Right"/>
 </Border>

Silverlight version 3.0

3

There are 3 best solutions below

1
sircodesalot On

To augment values, use a class that implements an IValueConverter, which is described here:

http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

In essence, a class that implements IValueConverter will intercetpt the value in a method called Convert. The value you return from this method is the value you really want to display. Consider:

namespace Sharp {

    public class MyConverter : IValueConverter {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            // First cast the value to an 'int'.
            Int32 theInputtedValue = (Int32)value;

            // Then return the newly formatted string.
            return String.Format("{0}% Completed", theInputtedValue);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            throw new NotImplementedException();
        }
    }

}

Notice in the example above the value converter is in the namespace Sharp. Now we add this to the XAML definition:

<Window x:Class="Sharp.MyWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 

         xmlns:lol="clr-namespace:Sharp">

The last line is the namespace where our value converter exists (that is, lol will now point to the Sharp CLR-namespace.

Next we add the class to our Window resources:

<Window.Resources>
    <lol:MyConverter x:Key="TheValueConverter" />
</Window.Resources>

this creates an instance of the class that you can use in the XAML. So, so far our XAML looks like this:

<Window x:Class="Sharp.MyWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 

         xmlns:lol="clr-namespace:Sharp">

    <Window.Resources>
        <lol:MyConverter x:Key="TheValueConverter" />
    </Window.Resources>

Now we simply add it to your content presenter like so:

<ContentPresenter Content="{TemplateBinding Value, Converter={StaticResource TheValueConverter}}" ... />

This tells the ContentPresenter that when it goes to present the value, it should use the TheValueConverter instance, which is an instance of our ValueConverter. Two things to be careful of: (1) Make sure that you use the name of the instance (TheValueConverter) and not the class definition (MyConverter). (2) Make sure to wrap the instance name in {StaticResource}.

3
Chris W. On

Or... You could also just use StringFormat

<ContentPresenter x:Name="perHolder" 
       Content="{TemplateBinding Value, StringFormat='\{\0}&#37; Completed'}" 
       VerticalAlignment="Center" HorizontalAlignment="Right"/>

Hope this helps...

3
MACN On

Another option is to use inline elements, like runs:

<TextBlock>
   <Run Text="{TemplateBinding Value}"/>
   <Run Text="% Completed "/>
</TextBlock>

EDIT:

After looking at your example, I think you should not use content presenter in your template. Content presenter is for controls that can host content (Read:has a content property). Content presenter, when given a string as a content, will certainly display the string, and you may use it, but for strings your better bet is textblock. It also give oyu more control about how the string is displayed.

Also, my bad. TemplateBinding is picky about where it is available, and inline elements are out of his list. Your best bet is like Cris W. says, using stackpanel:

<Border x:Name="whiteBorder" >
     <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right">
        <TextBlock Text="{TemplateBinding Value}"/>
        <TextBlock Text="% Completed"/>
     </StackPanel>/>
</Border>