views:

2606

answers:

2

I want to show a list of Customer objects in a WPF ItemsControl. I've created a DataTemplate for this:

    <DataTemplate DataType="{x:Type myNameSpace:Customer}">
        <StackPanel Orientation="Horizontal" Margin="10">
            <CheckBox"></CheckBox>
            <TextBlock Text="{Binding Path=Number}"></TextBlock>
            <TextBlock Text=" - "></TextBlock>
            <TextBlock Text="{Binding Path=Name}"></TextBlock>
        </StackPanel>
    </DataTemplate>

So what I want basically is a simple list (with checkboxes) that contains NUMBER - NAME. Isn't there a way in which I can concat the number and name directly in the Binding part?

+21  A: 

There is StringFormat property (in .NET 3.5 SP1), which you probably can use. And usefull WPF binding cheat sheat can found here. If it doesn't help, you can allways write your own ValueConverter or custom property for your object.

Just checked, you can use StringFormat with multibinding. In your case code will be something like this:

<TextBlock >
<TextBlock.Text>
    <MultiBinding StringFormat=" {0} - {1}">
        <Binding Path="Number"/>
        <Binding Path="Name"/>
    </MultiBinding>
</TextBlock.Text>

I had to start format string with space, otherwise Visual Studio wouldn't build, but I think you will find way get around it :)

PiRX
Instead of the space you can use {}, e.g. StringFormat="{}{0} - {1}"
Bryan Anderson
Thanks, didn't know that! :)
PiRX
This is helpful stuff, thanks for everything!
Gerrie Schenck
Glad, I was able to help!
PiRX
You can also escape the braces with backslashes:<MultiBinding StringFormat="\{0\} - \{1\}">
hughdbrown
+1  A: 

You can also use a bindable run. Useful stuff, especially if one wants to add some text formatting (colors, fontweight etc.).

<TextBlock>
   <something:BindableRun BoundText="{Binding Number}"/>
   <Run Text=" - "/>
   <something:BindableRun BoundText="{Binding Name}"/>
</TextBlock>

Here's an original class:
Here are some additional improvements.
And that's all in one piece of code:

public class BindableRun : Run
    {
        public static readonly DependencyProperty BoundTextProperty = DependencyProperty.Register("BoundText", typeof(string), typeof(BindableRun), new PropertyMetadata(new PropertyChangedCallback(BindableRun.onBoundTextChanged)));

        private static void onBoundTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((Run)d).Text = (string)e.NewValue;
        }

        public String BoundText
        {
            get { return (string)GetValue(BoundTextProperty); }
            set { SetValue(BoundTextProperty, value); }
        }

        public BindableRun()
            : base()
        {
            Binding b = new Binding("DataContext");
            b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(FrameworkElement), 1);
            this.SetBinding(DataContextProperty, b);
        }
    }
cz_dl