1
votes

I have created an listview where the items are sorted under different categories. And I am trying to get the selectedItem of the listview to get into a property in my Viewmodel, I have followed the regular approach simply setting a binding to the SelectedItem property.

However, since I am now actually only setting the datacontext to my observable collection, and not touching the ItemsSource property (Or am I?), I believe Im missing some fancy xaml code to make the binding for SelectedItem work. Hopefully someone encountered similar issue. xaml code, and the 2 properties declared in the viewmodel is dispalyed below.

<UserControl.Resources>
    <CollectionViewSource x:Key="TileChangeType"                               
                  Source="{Binding TileChangeList.TileChangeListEntries}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="Type" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</UserControl.Resources>
<ListView Grid.Column="0" x:Name="gridTiles" VirtualizingPanel.IsVirtualizing="False" VirtualizingPanel.IsVirtualizingWhenGrouping="False"
                      DataContext="{StaticResource TileChangeType}"
                      SelectedItem="{Binding SelectedTileChange}"
      ItemsSource="{Binding IsAsync=True}">


            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type GroupItem}">
                                        <Expander IsExpanded="True">
                                            <Expander.Header>
                                                <TextBlock Background="Aqua" Text="{Binding Path=Name}"/>
                                            </Expander.Header>
                                            <ItemsPresenter />
                                        </Expander>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                    <GroupStyle.Panel>
                        <ItemsPanelTemplate>
                            <DataGridRowsPresenter/>
                        </ItemsPanelTemplate>
                    </GroupStyle.Panel>
                </GroupStyle>
            </ListView.GroupStyle>
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="X" DisplayMemberBinding="{Binding X}" />
                        <GridViewColumn Header="Y" DisplayMemberBinding="{Binding Y}" />
                        <GridViewColumn Header="Z" DisplayMemberBinding="{Binding Z}" />
                        <GridViewColumn Header="Type" DisplayMemberBinding="{Binding Type}" Width="40"/>
                    </GridView.Columns>
                </GridView>
            </ListView.View>

            </ListView>

The model "SelectedTileChange" is declared as following:

    public TileChange SelectedTileChange
    {
        get;
        set;
    }

    //Class contains an Observable Collection of the TileChange class (same class as SelectedItem is binding to)
    //E.g. ObservableCollection<TileChange> tileChangeListEntries;
    public TileChangeList TileChangeList
    {
        get;
        set;
    }
1

1 Answers

1
votes

Assuming the datacontext of the usercontrol is set to the viewmodel that contains the SelectedTileChange property, you can bind to the SelectedItem property like this:

SelectedItem="{Binding DataContext.SelectedTileChange, 
              RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"

This will find the usercontrol, and bind to the SelectedTileChange property on its datacontext.

But normally you would just bind the ListView directly to the CollectionViewSource instead of setting its datacontext. That way you don't need to create this kind of RelativeSource binding:

<ListView ItemsSource="{Binding Source={StaticResource TileChangeType}}"
          SelectedItem="{Binding SelectedTileChange}" />