locked
FlipView - Redundant Loaded Events

    Question

  • In the (at least) Standard virtualization mode for the FlipView I am getting a Loaded event for an item that is already in the tree and has already had a Loaded event. Since we can't rely on correct eventing we have to track this stuff ourselves.

    This seems to happen on the first and last items when you wrap around the items source. I have an isolation where I have 8 items and 3 or 4 are in the vtree at any time. Here is a sequence:

    Start: 3 items Loaded and in tree and first is shown.

    Next Item: 2nd item shows but we get Loaded event for the first again, followed by an Unloaded event for it - first item still in vtree

    It won't happen again until you wrap and may be on the last item.

    Is there a workaround such that we can receive reliable Loaded/Unloaded events from the FlipView? This is pretty basic stuff to not be working - or am I doing something wrong somehow, wrong assumptions? - again the isolation is as simple as it gets?

    Thanks

    Monday, August 11, 2014 2:00 PM

Answers

  • I will file the bug.

    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.

    • Marked as answer by tfz4364 Wednesday, August 13, 2014 5:51 PM
    Wednesday, August 13, 2014 4:34 PM
    Moderator

All replies

  • It's really difficult to say what's going wrong without having a project that shows the problem.

    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.

    Monday, August 11, 2014 7:43 PM
    Moderator
  • Hi Matt - Can I attach a small VS project here? I would have originally but didn't see anything obvious.

    Thanks

    Monday, August 11, 2014 8:58 PM
  • Hi Matt.

    Here is MainPage C# and xaml you can drop in. I can still send you the proj if you want. Nothing weird to figure out here. I track items loaded by hash and print counts on each load. After the app comes up hit next button and you'll see the first item is loaded (a second consecutive time) and then unloaded while already in the vtree. Still there (as it should) after the seemingly spurious events.

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using Windows.UI.Xaml.Shapes;
    using Windows.UI;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Media;
     
    // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
     
    namespace FlipTest2
    {
        public class Data
        {
            public Data(Rectangle rect)
            {
                Rect = rect;
            }
            public Rectangle Rect { getset; }
        }
     
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class MainPage : Page
        {
            // track loaded count by hash
            Dictionary<intint> track = new Dictionary<intint>();
            // our data model
            List<Data> _Rects = new List<Data>();
            const int nItems = 8;
            public List<Data> Rects { get { return _Rects; } }
            public int Index
            {
                get { return (int)GetValue(IndexProperty); }
                set { SetValue(IndexPropertyvalue); }
            }
            public static readonly DependencyProperty IndexProperty =
                DependencyProperty.Register("Index"typeof(int), typeof(MainPage), new PropertyMetadata(0));
            public MainPage()
            {
                this.InitializeComponent();
                DataContext = this;
                List<SolidColorBrush> colors = new List<SolidColorBrush>()
                {
                    new SolidColorBrush(Colors.Red),
                    new SolidColorBrush(Colors.Green),
                    new SolidColorBrush(Colors.Blue),
                    new SolidColorBrush(Colors.Orange),
                    new SolidColorBrush(Colors.Yellow),
                    new SolidColorBrush(Colors.Magenta),
                    new SolidColorBrush(Colors.Cyan),
                    new SolidColorBrush(Colors.Purple)
                };
                for (int i = 0i < nItemsi++)
                {
                    Rectangle rect = new Rectangle()
                    {
                        Width = 100,
                        Height = 100,
                        Fill = colors[i]
                    };
                    Rects.Add(new Data(rect));
                    track.Add(rect.GetHashCode(), 0);
                }
                Index = 0;
            }
            void im_Unloaded(object senderRoutedEventArgs e)
            {
                int hash = (sender as ContentPresenter).Content.GetHashCode();
                track[hash]--;
                PrintTrack("Unloaded"hash);
                PrintItems();
                Debug.WriteLine("");
            }
            void im_Loaded(object senderRoutedEventArgs e)
            {
                int hash = (sender as ContentPresenter).Content.GetHashCode();
                track[hash]++;
                PrintTrack("Loaded  "hash);
                PrintItems();
                Debug.WriteLine("");
            }
            private void PrintTrack(string sint hash)
            {
                Debug.WriteLine(string.Format("{0}  {1:X8}  =================="shash));
                foreach (var kv in track)
                {
                    var count = kv.Value;
                    Debug.WriteLine(string.Format("   Hash  Item  {0:X8}   # {1}   {2}"kv.Keycountcount > 1 ? "Item Loaded 2nd Time without Unloaded" : ""));
                }
                Debug.WriteLine("---------------------------------------------");
            }
            void PrintItems()
            {
                foreach (var c in flipView1.ItemsPanelRoot.Children)
                {
                    Debug.WriteLine(string.Format("   VTree Item  {0:X8}", ((c as ContentControl).Content as Data).Rect.GetHashCode()));
                }
            }
            private void Button_Click_1(object senderRoutedEventArgs e)
            {
                Debug.WriteLine("PREV ========================================================================");
                Index = (Index + nItems - 1% nItems;
            }
            private void Button_Click_2(object senderRoutedEventArgs e)
            {
                Debug.WriteLine("NEXT ========================================================================");
                Index = (Index + 1% nItems;
            }
        }
     
    }
     
    

    <Page
        x:Class="FlipTest2.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:FlipTest2"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="5*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <FlipView x:Name="flipView1" Width="480" Height="270" 
                  BorderBrush="Black" BorderThickness="1"
                  ItemsSource="{Binding Rects}"
                  SelectedIndex="{Binding Index, Mode=TwoWay}"
                  VirtualizingStackPanel.VirtualizationMode="Standard" >
                <FlipView.ItemTemplate>
                    <DataTemplate>
                        <ContentPresenter Content="{Binding Rect}" Grid.Row="0" Loaded="im_Loaded" Unloaded="im_Unloaded"/>
                    </DataTemplate>
                </FlipView.ItemTemplate>
            </FlipView>
            <StackPanel Grid.Row="1" HorizontalAlignment="Center">
                <Button Content="Prev" Click="Button_Click_1"/>
                <Button Content="Next" Click="Button_Click_2"/>
            </StackPanel>
        </Grid>
        
    </Page>
    

    Monday, August 11, 2014 10:01 PM
  • I see what you're saying.  Assuming we can't change this, what's the underlying issue you're trying to solve?


    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.

    • Marked as answer by tfz4364 Tuesday, August 12, 2014 7:45 PM
    • Unmarked as answer by tfz4364 Wednesday, August 13, 2014 5:51 PM
    Tuesday, August 12, 2014 2:33 PM
    Moderator
  • Thanks Matt -

    Obviously we have a workaround by tracking ourselves. Unfortunately our client wrote a whole bunch of code to get around this before we could offer this workaround. They are doing some heavy initialization/deinitialization on the events and when they saw the spurious - they got to work!

    I was hoping there might be something going on such that we could lose the spurious events by some trick or setting without self tracking - which won't work in all cases. Sounds not

    Should I submit this as a bug through more formal channels?

    Thanks again

    Tuesday, August 12, 2014 5:02 PM
  • I will file the bug.

    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.

    • Marked as answer by tfz4364 Wednesday, August 13, 2014 5:51 PM
    Wednesday, August 13, 2014 4:34 PM
    Moderator