Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple WPF formatting question

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!

like image 581
Minnow Noir Avatar asked Mar 03 '10 12:03

Minnow Noir


2 Answers

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

like image 73
SysAdmin Avatar answered Oct 21 '22 04:10

SysAdmin


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.

like image 34
slugster Avatar answered Oct 21 '22 02:10

slugster