Question

Rather than declaring a tab for each of the ObservableCollections explicitly as in the first TabControl below I need them to generate dynamically as in the second TabControl and have the ItemsSource of the nested ListView set to each of the nested ObservableCollections.

In other words: Why aren't the ItemSource bindings of the nested ListViews in the second TabControl working? Is there a way to set the index of the nested ObservableCollection to the index of the containing ObservableCollection?

Or: How do I make the second dynamic TabControl and nested ListViews look like the first static TabControl and nested ListViews?

using System.Collections.ObjectModel;
using System.Windows;

namespace GridViewColumns2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ViewModel viewModel = new ViewModel();

            viewModel.ThingCollections = new ObservableCollection<ThingCollection>();

            viewModel.ThingCollections.Add(new ThingCollection { Name = "One" });
            viewModel.ThingCollections[0].Things = new ObservableCollection<Thing>();
            viewModel.ThingCollections[0].Things.Add(new Thing { Name = "One.One" });
            viewModel.ThingCollections[0].Things.Add(new Thing { Name = "One.Two" });
            viewModel.ThingCollections[0].Things.Add(new Thing { Name = "One.Three" });


            viewModel.ThingCollections.Add(new ThingCollection { Name = "Two" });
            viewModel.ThingCollections[1].Things = new ObservableCollection<Thing>();
            viewModel.ThingCollections[1].Things.Add(new Thing { Name = "Two.One  " });
            viewModel.ThingCollections[1].Things.Add(new Thing { Name = "Two.Two" });
            viewModel.ThingCollections[1].Things.Add(new Thing { Name = "Two.Three" });

            DataContext = viewModel;
        }
    }

    public class ViewModel
    {
        public ObservableCollection<ThingCollection> ThingCollections { get; set; }
    }

    public class ThingCollection
    {
        public string Name { get; set; }

        public ObservableCollection<Thing> Things { get; set; }
    }

    public class Thing
    {
        public string Name { get; set; }
    }
}



<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <TabControl>
        <TabItem>
            <TabItem.Header>One</TabItem.Header>
            <TabItem.Content>
                <ListView ItemsSource="{Binding Path=ThingCollections[0].Things}">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Width="120" Header="Name" DisplayMemberBinding="{Binding Name}" />
                        </GridView>
                    </ListView.View>
                </ListView>
            </TabItem.Content>
        </TabItem>
        <TabItem>
            <TabItem.Header>Two</TabItem.Header>
            <TabItem.Content>
                <ListView ItemsSource="{Binding Path=ThingCollections[1].Things}">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Width="120" Header="Name" DisplayMemberBinding="{Binding Name}" />
                        </GridView>
                    </ListView.View>
                </ListView>
            </TabItem.Content>
        </TabItem>
    </TabControl>

    <TabControl Grid.Column="1" ItemsSource="{Binding Path=ThingCollections}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" />
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <ListView ItemsSource="{Binding Path=ThingCollections[0].Things}">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Width="120" Header="Name" DisplayMemberBinding="{Binding Name}" />
                        </GridView>
                    </ListView.View>
                </ListView>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>


</Grid>
Was it helpful?

Solution

When you're in a DataTemplate, the DataContext is already that of the item (in your case, a ThingCollection class.

So instead of:

<ListView ItemsSource="{Binding Path=ThingCollections[0].Things}">

Use:

<ListView ItemsSource="{Binding Path=Things}">

To diagnose future binding errors, hit F5 (start debugging) and then take a look in the Output Window. All binding errors will be recorded there. In this case, it would've indicated that it cannot find a property named ThingCollections in the object ThingCollection.

OTHER TIPS

Remove ThingCollections[0]. in BindingPath. The DataContext will be set for you to the right ThingCollection.

<ListView ItemsSource="{Binding Path=Things}">
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top