0
votes

I'm trying to implement Undo function for my UWP app that has a listview that can be swiped to take action (like left swipe remove, right swipe archive). My xaml summary for the swipe listview is like this

<controls:SwipeListView.ItemTemplate>
    <DataTemplate>
        <Grid Visibility="{Binding HideForUndo, Converter={StaticResource BooleanNegationToVisibilityConverter}}">
            SomeContents here...
        </Grid>
    </DataTemplate>
</controls:SwipeListView.ItemTemplate>

And the container style is like this

<controls:SwipeListView.ItemContainerStyle>
    <Style TargetType="controls:SwipeListViewItem">
        <Setter Property="TabNavigation" Value="Local"/>
        <Setter Property="IsHoldingEnabled" Value="True"/>
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="VerticalContentAlignment" Value="Top"/>
        <Setter Property="Padding" Value="0,0,0,0"/>
        <Setter Property="MinHeight" Value="0"/>
    </Style>
</controls:SwipeListView.ItemContainerStyle>

The problem is that after I hide the selected item, there will be some space between the items above and below the selected item. Only when the Undo timer expired and removed the selected item can the space be gone. I can see that the selected item has collapsed and the item below it did move up, but there is just some space.

I found a question that is similar to mine: How do you hide a ListView Item placeholder when it's DataTemplate child is collapsed? However it seems doesn't work for me even if I set MinHeight and Padding to 0.


Edit: After testing, I found that this is not related to ListView but to the SwipeListView.
enter image description here

The SwipeListView added many other controls to it, only the highlighted part will be set to collapsed, other parts still visible.

1
What is your SwipeListViewItem? Could you share a minimal reproducible example that can reproduce your issue? For a normal ListView and ListViewItem, setting MinHeight to 0 should be able to work. - Jay Zuo
@JayZuo-MSFT Thanks! I tested in the branch that before Swipe action being introduced and it works. But swipeviewlist is really complicated. I think I will dig into swipeviewlist related code for now and I may give you more information. - litaoshen
@JayZuo-MSFT I updated the question and I'm working on binding the top grid's visibility to the highlighted grid's visibility. - litaoshen
Are you using this SwipeListView? Do you just want to hide the SwipeListView when left swipe? - Jay Zuo
@JayZuo-MSFT Yes, though we modified it a little bit. I'm trying to hide the selected item when tap a certain button, the visibility of the control inside the contentpresenter or itempresenter can be binded to a property inside the selected item, but seems that the whole grid that contains everything cannot be accessed. Is there anyway to hide the whole grid(I mean the swipelistview selecteditem) when hide the control inside contentpresenter? - litaoshen

1 Answers

1
votes

I don't know the details about how you implement the "HideForUndo" function. But if you can get the selected item, I think you can try with ItemsControl.ContainerFromItem method to get the item container which in SwipeListView is the SwipeListViewItem. After having the SwipeListViewItem, you can set SwipeListViewItem.Visibility to Visibility.Collapsed to hide the whole item.

From the source code of SwipeListView class, we can find it is derived from ListView class and ListView inherits from ItemsControl, so we can use ItemsControl.ContainerFromItem method with SwipeListView.

Here using the Demo in SwipeListView for example:

private void SwipeListView_ItemSwipe(object sender, ItemSwipeEventArgs e)
{
    var item = e.SwipedItem as EmailObject;
    if (item != null)
    {
        if (e.Direction == SwipeListDirection.Left)
        {
            item.Unread = !item.Unread;
        }
        else
        {
            //(Resources["Emails"] as EmailCollection).Remove(item);
            var swipeListView = sender as SwipeListView;
            var itemContainer = swipeListView?.ContainerFromItem(item) as SwipeListViewItem;
            if (itemContainer != null)
            {
                itemContainer.Visibility = Visibility.Collapsed;
            }
        }
    }
}

In the demo, it originally remove the item form items source. I comment out its code and hide the SwipeListViewItem instead.