locked
Windows.UI.Xaml.Controls.ListViewBase (GridView / ListView) - buggy behavior when reordering items

    Question

  • I am experiencing the following issues when performing reorder operations in a ListView:

    • When the ListView is in a Popup, items disappear beneath the Popup during reordering operations
    • after reordering, the relocated items tend to disappear (I'm using a DataTemplate to bind a display_object property as the Child of a Border)

    Items disappearing beneath popups during drag operations is apparently a known issue (e.g., topic="GridView/ListView item not displayed while dragging inside popup" &  topic= "bug of listview in a popup"). 

    @MS:  Is that behavior officially considered a bug, and if so when might we see a fix?

    The second issue -  items not displaying properly after a reorder operation - happens whether or not the ListView is in a Popup.  So far, the best workaround I have found (~90% success rate) is to use an ObservableCollection with a CollectionChanged event handler.  Whenever the ObservableCollection's state changes, I store the current selection set, nullify the ItemsSource binding, delay for .5 seconds, re-establish the ItemsSource binding, then re-select items (good grief!):

                List<MyItem> currently_selected = selected_items();
                list_view.ItemsSource = null;
                await Task.Delay(TimeSpan.FromSeconds(.5));
                list_view.ItemsSource = MyItems;
                foreach (MyItem mi in currently_selected)
                {
                    if (MyItems.Contains(mi)) list_view.SelectedItems.Add(mi);
                }

    The half-second delay is the minimal value that seems to (usually) do the trick.

    The display object is nothing exotic - just a StackPanel containing a few Grid-wrapped TextBlocks.

    In theory, <DataTemplate><Border Child={Binding display_object_property}></DataTemplate> should work just fine, correct?

    Wednesday, February 26, 2014 9:22 PM

All replies

  • 1) Yes this is a known bug. It occurs because popups always have the highest index in z-order, so everything else appears below them.  I don't have a timeline for the fix.

    2) I would have to see exactly what you're doing in order with the reorder to give you an idea of what's going on.


    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Thursday, February 27, 2014 1:28 PM
    Moderator
  • Hi Matt,

    Thanks for the response.

    1) Yes this is a known bug. It occurs because popups always have the highest index in z-order, so everything else appears below them.  I don't have a timeline for the fix.

    Good to know.

    2) I would have to see exactly what you're doing in order with the reorder to give you an idea of what's going on.

    The code below exhibits the same issue.

    ################ MainPage.xaml ###############

    <Page
        x:Class="ListViewTest.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:ListViewTest"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">

        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" x:Name="main_grid" />

    </Page>

    ################ MainPage.xaml.cs ###############

    using Windows.UI.Xaml.Controls;

    namespace ListViewTest
    {

        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
                main_grid.Children.Add(new ListviewReorderTester());
            }
        }
    }

    ################ ListviewReorderTester.xaml ###############

    <UserControl
        x:Class="ListViewTest.ListviewReorderTester"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:ListViewTest"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">

        <ListView x:Name="list_view" SelectionMode="Multiple" CanDragItems="True" CanReorderItems="True" AllowDrop="True">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Border BorderBrush="White" CornerRadius="5" BorderThickness="2" Child="{Binding display_object}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        
    </UserControl>

    ################ ListviewReorderTester.xaml.cs ###############

    using System.Collections.ObjectModel;
    using Windows.UI;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Media;

    namespace ListViewTest
    {
        public sealed partial class ListviewReorderTester : UserControl
        {
            ObservableCollection<Item> item_set { get; set; }

            public ListviewReorderTester()
            {
                this.InitializeComponent();
                item_set = new ObservableCollection<Item>();
                list_view.ItemsSource = item_set;
                for (int i = 0; i < 10; i++)
                {
                    item_set.Add(new Item());
                }
            }
        }

        public class Item
        {
            public StackPanel display_object { get; set; }

            public Item()
            {
                display_object = new StackPanel { Orientation = Orientation.Horizontal };
                Grid red = grid("Red", new SolidColorBrush(Colors.Red));
                Grid blue = grid("Blue", new SolidColorBrush(Colors.Blue));
                Grid green = grid("Green", new SolidColorBrush(Colors.Green));
                foreach (Grid g in new Grid[] { red, blue, green })
                {
                    display_object.Children.Add(g);
                }
            }

            Grid grid(string t, SolidColorBrush bg)
            {
                TextBlock tb = new TextBlock
                {
                    Text = t,
                    FontSize = 20,
                    Foreground = new SolidColorBrush(Colors.White)
                };
                Grid g = new Grid
                {
                    Background = bg
                };
                g.Children.Add(tb);
                return g;
            }
        }
    }

    Thursday, February 27, 2014 5:50 PM
  • This is very weird. I can reproduce and I am investigating.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Thursday, February 27, 2014 7:24 PM
    Moderator
  • This is very weird. 

    It gets weirder.   I played a little game with my test app above and found that moving any single item will cause it to flip-flop back and forth between visible and invisible/dot states.  Consistent across about 100 iterations.


    Thursday, February 27, 2014 7:57 PM
  • Similar consistent pattering happens when moving multiple items.

    It seems to me that the problem is arising with the Action.Remove phase of the reorder operation.  You can add items all day long and not see the issue.

    Thursday, February 27, 2014 8:15 PM
  • Yes I noticed that as well. The container (border) doesn't disappear, just the contents. If you give the border a width/height, you'll see that it doesn't disappear.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Thursday, February 27, 2014 8:15 PM
    Moderator
  • It seems to me that the problem is arising with the Action.Remove phase of the reorder operation. 

    Disregard.  Doing the unbind-wait-rebind thing works regardless of which Action (Add or Remove) I filter out individually.   

            async private void item_set_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
            {
                if (e.Action.ToString() == "Remove") return;
                List<Item> currently_selected = selected_items();
                list_view.ItemsSource = null;
                await Task.Delay(TimeSpan.FromSeconds(.5));
                list_view.ItemsSource = item_set;
                foreach (Item item in currently_selected)
                {
                    if (item_set.Contains(item)) item_viewer.SelectedItems.Add(item);
                }
            }
    Thursday, February 27, 2014 8:52 PM
  • FYI we are still checking into this behavior. I will update when I know more.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Tuesday, March 4, 2014 3:28 PM
    Moderator
  • Bumping to ask:  Any progress at all on this, Matt?

    Friday, April 11, 2014 8:40 AM
  • Sorry about that - I was waiting on a response from someone that I never heard from. I'll check on this.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Friday, April 11, 2014 1:46 PM
    Moderator