Trouble binding selected item in nested Listview

2019-07-25 02:48发布

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");
            }
        }

1条回答
等我变得足够好
2楼-- · 2019-07-25 03:09

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!

查看更多
登录 后发表回答