1

I currently use a listview nested inside a listview as a way to show a Knockout style tournament graphically, backed up in ViewModel by SectionTreeOne, which contains a List of Lists of objects "TournamentNode". I cannot however get my selected "Tournament Node" to bind when I click on it.

  <Grid Grid.Row="2">
          <ListView ItemsSource="{Binding SectionTreeOne}">
                                <ListView.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <VirtualizingStackPanel Orientation="Horizontal" />
                                    </ItemsPanelTemplate>
                                </ListView.ItemsPanel>
                                <ListView.ItemTemplate >
                                    <DataTemplate>
                                        <ListView ItemsSource="{Binding}" SelectionMode="Single" 
                                                  SelectedItem="{Binding SelectedTournamentNode}">
                                            <ListView.ItemTemplate>
                                                <DataTemplate>
                                                    <TextBlock Text="{Binding Name}" />
                                                </DataTemplate>
                                            </ListView.ItemTemplate>
                                        </ListView>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                        </Grid>

C# binding:

Collection

public List<List<TournamentNodeModel>> SectionTreeOne
            {
                get { return _sectionTreeOne; }
                set
                {
                    _sectionTreeOne = value;
                    base.OnPropertyChanged("SectionTreeOne");
                }
            }

Selected Item:

public TournamentNodeModel SelectedTournamentNode
        {
            get { return _selectedTournamentNode; }
            set
            {
                if (value == _selectedTournamentNode)
                    return;

                _selectedTournamentNode = value;
                base.OnPropertyChanged("SelectedTournamentNode");
            }
        }
andrew rea
  • 23
  • 5

1 Answers1

3

Try with the folowing binding:

SelectedItem="{Binding SelectedTournamentNode, Mode=TwoWay}"

Keep in mind that WinRT always use the OneWay binding mode as default unlike in WPF where it automatically selects a binding mode depending on the property nature or accessibility.

A good principle I used with WinRT to avoid this kind of mistake is to always explicitely specify the binding mode.


So I finally figured out what were the mistakes in your binding. Firstly, the SelectedItem binding mode has to be set to TwoWay explicitely as I stated above.

Secondly, the nested list was binding to an inner list in the SectionTreeOne list, therefore if you want to bind SelectedItem to a property on your view model, you have to rebind this property to the DataContext of the parent list using named elements. You were actually trying to bind to a non-existant property on the inner list instead of binding to the view model where the property is located.

<ListView x:Name="listView" ItemsSource="{Binding SectionTreeOne}">
    ...
    <ListView.ItemTemplate >
        <DataTemplate>
            <ListView ItemsSource="{Binding}" SelectionMode="Single" 
                      SelectedItem="{Binding Path=DataContext.SelectedTournamentNode, ElementName=listView, Mode=TwoWay}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Do read the Visual Studio debugger output, it has really useful information about binding errors that could occur in the binding chain, especially if you bind a list nested in another list, it will save you lot of headaches!

Ucodia
  • 7,410
  • 11
  • 47
  • 81
  • Unfortunately this has not worked. I am unsure as to why as it seems to be a pretty straight forward binding. I have this implemented and working for non nested ListViews, but selection doesn't seem to be working for the nested ones at all. – andrew rea Mar 22 '13 at 19:35
  • Have you checked the debugger console to see if there is any binding error? – Ucodia Mar 22 '13 at 23:10
  • Yeah, the SelectedItem property in the viewmodel is not being reached at all. I have added the C# to the above post. I am beginning to think I cannot select the item because it is not an observable collection. do you think that could be it? – andrew rea Mar 22 '13 at 23:23
  • ItemsControl such as the ListView accept binding to any collection that implements the `IEnumerable` interface so this won't be an issue in your case as you bind to a `List`. `ObservableCollection` is simply a collection that notifies the interface whenever you use the `Add`, `Remove` and `Clear` (not sure for this one) methods of the collection. Therefore you don't have to worry to raise the `OnPropertyChanged` yourself when the collection changes. – Ucodia Mar 24 '13 at 20:38
  • Do you see any "System.Windows.Data Information: 40 : BindingExpression path error: 'MyProperty'" error in the Visual Studio debugger console when you run your application? This information is really useful for tracking down errors in the binding chain. – Ucodia Mar 24 '13 at 20:38
  • By reproducing and reading the Visual Studio debugger console, I found out what was the error and it seems quite obvious to me. I will update my answer with the resolution. – Ucodia Mar 24 '13 at 20:57
  • Your answer now works. Thanks so much. I am a xaml & MVVM novice, do you know of any good tutorials which can help me learn more about advanced bindings? – andrew rea Mar 24 '13 at 22:04
  • 1
    Well, it is all about training and practicing, especially with MVVM. Binding is not so hard to understand but it is really important to fully understand its capabilities because it is the glue between XAML and MVVM. Learn about the binding modes and debugging and be careful with documentation treating of WPF because there is quite a few properties and bevahior that were suppressed in Windows 8! Concerning MVVM, even though I read good books covering the subject, I only learnt it by practicing because that is the only way to fully understand its inner concepts. Avoid using frameworks at first! – Ucodia Mar 25 '13 at 08:17