stiank81
stiank81

Reputation: 25686

WPF: Set Binding-property for ListBox-binding

I have a listbox where I bind the ItemsSource to a collection stored in the set DataContext object. This makes the list displayed using the ToString() function.

<ListBox ItemsSource="{Binding SomeCollection}"></ListBox>                    

Now I want to display a property for the objects in the collection instead. So I want to define a template etc to do this on all the objects in the bound list. I tried a variety of different approaches without success. I'd like to do something like this:

<ListBox ItemsSource="{Binding SomeCollection}">
    <ListBox.Template>
        <ControlTemplate>                                
            <ListViewItem Content="{Binding ThePropertyOnElm}"></ListViewItem>
        </ControlTemplate>
    </ListBox.Template>
</ListBox>

Can anyone help me make this right?

Upvotes: 13

Views: 14267

Answers (4)

Mark Synowiec
Mark Synowiec

Reputation: 5445

I think this is what youre wanting to do:

<ListBox ItemsSource="{Binding SomeCollection}">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="{x:Type local:YourDataType}">                                
            <TextBlock Text="{Binding ThePropertyOnElm}" />
        </ControlTemplate>
    </ListBox.ItemTemplate>
</ListBox>

The Template for the ListBox is going to modify how the actual listbox looks, and itemtemplate is going to control how the individual items in the listbox will look. I changed the controltemplate into a DataTemplate and assigned it to the type of YourDataType. Also, I used a textblock within the data template instead of listboxitem since the datatemplate is being assigned to the listboxitem (which should contain some type of content instead of another listboxitem).

i havent tried compiling this so it might not be exactly correct. if it doesnt let me know and ill take the extra steps!

Upvotes: 12

RoelF
RoelF

Reputation: 7573

you don't need to specify a template, you can just use the DisplayMemberPath property, like so:

<ListBox ItemsSource="{Binding SomeCollection}" DisplayMemberPath="ThePropertyOnElm" />

hope this helps!

Upvotes: 37

Pete OHanlon
Pete OHanlon

Reputation: 9146

Here's a sample I recently posted on Code Project:

    <Window
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2006" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
      x:Class="GameSampleApp.Window1"
      x:Name="Window"
      Title="Sample App"
      Width="380" Height="240">
      <Window.Resources>
        <Style TargetType="ListBox">
          <Setter Property="Control.FontFamily" Value="Tahoma" />
          <Setter Property="Control.FontSize" Value="10" />
        </Style>
        <Style x:Key="FontStyle">
          <Setter Property="Control.FontFamily" Value="Verdana" />
          <Setter Property="Control.FontStyle" Value="Italic" />
          <Setter Property="Control.FontSize" Value="12"/>
        </Style>
        <DataTemplate x:Key="GamePersonTemplate">
          <Grid>
            <Grid.RowDefinitions>
              <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
              <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock Width="40" Grid.Column="0" Text="{Binding Name, Mode=OneWay}" />
          </Grid>
        </DataTemplate>
      </Window.Resources>
      <Grid x:Name="LayoutRoot">
      <ListBox Padding="3" HorizontalAlignment="Left" Width="Auto" 
          ItemTemplate="{DynamicResource GamePersonTemplate}" 
          ItemsSource="{Binding}" VerticalAlignment="Top" Height="Auto"/>
      </Grid>
  </Window>

In this sample, I set the ItemsSource to point to the datacontext binding, which could be anywhere up the visual tree. The item template is defined in the Window.Resources, but could just as well be defined in a separate ResourceDictionary. Basically, this items template is going to show a single textblock for each item row, but it could be made to be much more complicated if necessary; that's the beauty of WPF.

Upvotes: 1

Tor Haugen
Tor Haugen

Reputation: 19627

Use the Path binding property:

<ListBox ItemsSource="{Binding SomeCollection}">
    <ListBox.Template>
        <ControlTemplate>                                
            <ListViewItem Content="{Binding Path=ThePropertyOnElm}"></ListViewItem>
        </ControlTemplate>
    </ListBox.Template>
</ListBox>

Note: The reason for the somewhat confusing name (Path) is that it can be extended to sub-properties etc. So if the ThePropertyOnElm property returns an object with a property called Name, you could write {Binding Path=ThePropertyOnElm.Name} etc.

Upvotes: 2

Related Questions