Caliburn.Micro icon indicating copy to clipboard operation
Caliburn.Micro copied to clipboard

[UWP] ListViewItem lost context after manipulations with IGrouping

Open dmitry-kugach opened this issue 6 years ago • 2 comments

Hey. I've got an issue when trying to use SemanticZoom with CollectionViewSource. When trying to delete group and insert/add it back after update - some/all of items lost context and attached actions don't fire.

DataTemplates


    <DataTemplate x:Key="MovementGroupByDateDataTemplate">
        <Grid d:DataContext="{d:DesignInstance movementsItemViewModels:MovementsGroupedByTimeItemViewModel}"
              micro:Action.TargetWithoutContext="{Binding ElementName=Root, Path=DataContext}">
            <Grid Margin="12,21,12,9">

            </Grid>
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="MovementDataTemplate">
        <controls:SlidableListItem d:DataContext="{d:DesignInstance movementsItemViewModels:MovementItemViewModel}"
                                   x:Name="GridItem"
                                   
                                   RightIcon="Delete" RightBackground="{StaticResource DeleteBrush}"
                                   RightLabel="Delete"
                                   
                                   LeftIcon="Edit" LeftBackground="{StaticResource AccountBrush}"
                                   LeftLabel="Edit"
                                   
                                   ActivationWidth="150" MouseSlidingEnabled="True"
                                   micro:Message.Attach="[Event LeftCommandRequested] = [Action Edit()];
                                                         [Event RightCommandRequested] = [Action Delete()]"
                                   
                                   IsLeftCommandEnabled="{Binding IsSelected}" 
                                   IsEnabled="{Binding IsSelected}"
                                   IsRightCommandEnabled="{Binding IsSelected}">

            <Grid>
                
            </Grid>
        </controls:SlidableListItem>
    </DataTemplate>

Page


    <Page.Resources>
        <CollectionViewSource x:Name="AllMovementsCollection" x:Key="AllMovementsCollection"
                              Source="{Binding Path=All.Items, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                              IsSourceGrouped="True"/>
    </Page.Resources>
    <Grid x:Name="Root">
            <SemanticZoom>
                <SemanticZoom.ZoomedOutView>
                    <ListView ItemsSource="{Binding Path=CollectionGroups, Source={StaticResource AllMovementsCollection}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                              MaxWidth="{StaticResource MaxWidth}" 
                              HorizontalAlignment="Stretch" HorizontalContentAlignment="Center"
                              ItemContainerStyle="{StaticResource WalletListViewItemWithoutMargin}"
                              ItemTemplate="{StaticResource ZoomOutMovementGroupByDateDataTemplate}"
                              SelectionMode="Single" ScrollViewer.VerticalScrollBarVisibility="Hidden"/>
                </SemanticZoom.ZoomedOutView>
                <SemanticZoom.ZoomedInView>
                    <ListView ItemsSource="{Binding Source={StaticResource AllMovementsCollection}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                              SelectedItem="{Binding All.SelectedMovement, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                              MaxWidth="{StaticResource MaxWidth}" 
                              HorizontalAlignment="Stretch" HorizontalContentAlignment="Center"
                              ItemContainerStyle="{StaticResource WalletListViewItemWithoutMargin}"
                              ItemTemplate="{StaticResource MovementDataTemplate}"
                              SelectionMode="Single" ScrollViewer.VerticalScrollBarVisibility="Hidden"
                              ShowsScrollingPlaceholders="True">
                        <ListView.GroupStyle>
                            <GroupStyle HidesIfEmpty="True" HeaderTemplate="{StaticResource MovementGroupByDateDataTemplate}"/>
                        </ListView.GroupStyle>
                    </ListView>
                </SemanticZoom.ZoomedInView>
            </SemanticZoom>
     </Grid>

Code

var movementsGroup = MainContentViewModel.All.Items.First(gi => gi.Items.Any(i => i.Movement.Id == _deleteMovement.Movement.Id));
int groupIndex = MainContentViewModel.All.Items.IndexOf(movementsGroup);
                    
var groupMovements = new List<MovementItemViewModel>(movementsGroup.Items);
groupMovements.Remove(groupMovements.First(m => m.Movement.Id == _deleteMovement.Movement.Id));

MainContentViewModel.All.SelectedMovement = null;
MainContentViewModel.All.Items[groupIndex] = _viewModelFactoryService.ResolveViewModel<MovementsGroupedByTimeItemViewModel, IEnumerable<MovementItemViewModel>>(groupMovements); // IoC.Get

// or 

var movementsGroup = MainContentViewModel.Expenses.Items.First(gi => gi.Items.Any(i => i.Movement.Id == _deleteMovement.Movement.Id));
int groupIndex = MainContentViewModel.Expenses.Items.IndexOf(movementsGroup);
MainContentViewModel.Expenses.Items.RemoveAt(groupIndex);

movementsGroup.Items.Remove(_deleteMovement);
if (movementsGroup.Items.Any())
{
   await movementsGroup.RecalculateAmounts();
   if (groupIndex > MainContentViewModel.All.Items.Count)
   {
        MainContentViewModel.Expenses.Items.Add(movementsGroup);
   }
    else
   {
        MainContentViewModel.Expenses.Items.Insert(groupIndex, movementsGroup);
   }
}

Delete implemented this way, because if try to remove nested element itself - ListView doesn't update.

dmitry-kugach avatar Jan 22 '19 13:01 dmitry-kugach

I'm not sure off the top of head what's going wrong here, if you can provide a small sample that illustrates the problem I'll dig into it in more detail.

nigel-sampson avatar Jan 29 '19 21:01 nigel-sampson

https://github.com/dmitriywind/CaliburnIssueExample

Try to delete items inside 1 group (in diff orders).

dmitriywind avatar Feb 19 '19 11:02 dmitriywind