How can I prefix bound values in TextBlock controls in a StackPanel without using separate controls for the prefixes?
E.g., let's say I have a dialog that uses a TreeView to display a list of books, with the top nodes being the title, and a set of subordinate nodes for the other book attributes (ISBN, Author, etc.).
I have the binding working correctly, but my user wants the book attributes list to stack vertically, and, obviously, he wants each attribute node to have a descriptive prefix before the value (e.g., "Author: Erich Gamma" instead of just "Erich Gamma"). Inside my HDT and DT elements, I am using a StackPanel and TextBlock controls to display the values.
Must I use a separate TextBlock control for the prefix of each attribute
<!-- Works, but requires 2 controls to display the book author and the prefix stacks above the author -->
<TextBlock Text="Author: "/><TextBlock Text="{Binding Path=Author}" />
or is there a way to do this with a single TextBlock control for each node?
<!-- only one control, but doesn't work -->
<TextBlock Text="Author: {Binding Path=Author}" />
I know this must be a common issue, and I Googled for it and searched in the three WPF books I have, but I guess I don't know the right way to search for what I'm trying to say.
Thanks!
If you have .Net 3.5 SP1, you can easily achive this via StringFormat
<TextBlock Text="{Binding Path=Title, StringFormat= Title: {0}}" />
You can also do this
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="Author: {0}, Title: {1}">
<Binding Path="Author"/>
<Binding Path="Title"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
If you are not using SP1, Then you can use a ValueConverter
Quick dirty and simple method: use a converter, and pass the prefix text in as the converter parameter. Then in the converter all you do is prepend the converter parameter text to the binding text.
<TextBlock Text="{Binding Path=Title, Converter={StaticResource MyTextConverter}, ConverterParameter=Title}" />
<TextBlock Text="{Binding Path=ISBNNumber, Converter={StaticResource MyTextConverter}, ConverterParameter=ISBN}" />
<TextBlock Text="{Binding Path=AuthorName, Converter={StaticResource MyTextConverter}, ConverterParameter=Author}" />
public class MyTextConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is string)
{
return string.Format("{0}{1}{2}", parameter ?? "", !string.IsNullOrEmpty(parameter) ? " : " : "", value);
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
That was straight of the top of my head, excuse any small errors in it. This gets it done using just the one textblock. All you have to do is include the converter in the static resources of the xaml file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With