简体   繁体   中英

How to bind a list of lists to a Listbox in WPF?

I have a List of Lists in C# where each list contains 3 integers

List<List<int>> Data = new List<List<int>>();
data.Add(new List<int>{ 1, 2, 3});

Now in WPF i have a listbox where i want to bind these values to. The code below is the code i have now but as expected it says there are no "Item" properties.

<ListBox ItemsSource="{Binding Data}" HorizontalContentAlignment="Stretch">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="auto" />
        </Grid.RowDefinitions>

        <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Item1}" />
        <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Item2}" />
        <TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding Item3}" />
      </Grid>
    </DataTemplate>
  </ListBox>

Could someone explain what i have to do in order to get those numbers showing in the listbox?

Thanks in advance.

You would need to index your bindings within the ListView item template, like so:

<ListBox ItemsSource="{Binding Data}" HorizontalContentAlignment="Stretch">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="auto" />
        </Grid.RowDefinitions>

        <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding [0]}" />
        <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding [1]}" />
        <TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding [2]}" />
      </Grid>
   </DataTemplate>
</ListBox>

However if you plan to have a dynamic number of elements in each List<int> , you could place another ListView within the original ListView .

Also, this link: https://web.archive.org/web/20120814100526/http://msdn.microsoft.com/en-us/library/ms742451.aspx is really handy if you ever get stuck with binding paths!

You need to do the TextBlock lines like this:

<TextBlock Grid.Row="0"
           Grid.Column="0"
           Text="{Binding Path=[0]}" />
<TextBlock Grid.Row="0"
           Grid.Column="1"
           Text="{Binding Path=[1]}" />
<TextBlock Grid.Row="0"
           Grid.Column="2"
           Text="{Binding Path=[2]}" />

If your inner list will ALWAYS have 3 items, I would suggest making a model for binding. Something like -

    public class TripleIntObject
    {
        public int First { get; set; } 
        public int Second{ get; set; }
        public int Third{ get; set; }
    }

but hopefully your properties are named with more meaning.

So your list changes from List<List<int>> to List<TripleIntObject>

Then modify your TextBlocks accordingly -

<TextBlock Grid.Row="0"
           Grid.Column="0"
           Text="{Binding First}" />
<TextBlock Grid.Row="0"
           Grid.Column="1"
           Text="{Binding Second}" />
<TextBlock Grid.Row="0"
           Grid.Column="2"
           Text="{Binding Third}" />

If you plan on dynamic items, I would also suggest changing from List<TripleIntObject> to 'ObservableCollection` so that your view will be notified when any data changes. You can read more here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM