locked
ListView.ContainerContentChanging is not called when ItemsPanelTemplate is used

    Question

  • Hi,

    I was using a ListView to display my items (vertical default orientation) and did some code in its ContainerContentChanging event. I tried to change ListView orientation to horizontal (which works fine) but since then, ContainerContentChanging event is not called anymore. I'm using VS2013 Pro v12.0.30723.00 Update 3.

    Is it a known issue to be fixed or, am I missing something?

    Here's a simple sample code to reproduce it:

    XAML:

    <Page
        x:Class="App1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        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}">       
            <ListView x:Name="m_ListView" ContainerContentChanging="ListView_ContainerContentChanging">
                <!--Uncommenting the following 5 lines change the ListView orientation 
                    but then, ContainerContentChanging is not called anymore-->
                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
    
                <ListView.ItemTemplate>
                    <DataTemplate>
                            <TextBlock x:Name="m_Title" Margin="0" Text="{Binding m_szTitle}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>        
        </Grid>
    </Page>
    

    C#:

    using System.Collections.Generic;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Input;
    
    namespace App1
    {
        // Sample test class
        public class DataTest
        {
            public string m_szTitle {get; set;}
            public DataTest(string _szTitle)
            {
                m_szTitle = _szTitle;
            }
        };
        // Main Page
        public sealed partial class MainPage : Page
        {
            private List<DataTest> m_DataList = null;
    
            public MainPage()
            {
                this.InitializeComponent();            
            }
            protected override void OnNavigatedTo(Windows.UI.Xaml.Navigation.NavigationEventArgs e)
            {
                base.OnNavigatedTo(e);
                // Setup data
                m_DataList = new List<DataTest>();
                for(int i=0; i<10; i++)
                    m_DataList.Add(new DataTest("Title " + i));
                
                m_ListView.ItemsSource = m_DataList;
            }
            private void ListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
            {
                // This method is not called if ListView as ItemsPanel set in XAML...
                DataTest dataTest = args.Item as DataTest;
                System.Diagnostics.Debug.WriteLine("m_ListView_ContainerContentChanging called for item: " + (dataTest != null && dataTest.m_szTitle != null ? dataTest.m_szTitle : "Unkown"));
            }
        }
    }
    




    Monday, September 8, 2014 7:44 AM

All replies

  • I thought about using a GridView instead. By doing some tests I realized the same behavior occurred on GridView. ContainerContentChanging is not called if I set an ItemsPanel in my GridView:

    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <VariableSizedWrapGrid Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>

    If both ListView & GridView behave that way, I suspect there might be good reason for it. Then... why is it so? And, how can I be noticed of which new item is added to my ListView or GridView if ContainerContentChanging is not called?

    I'll be glad if someone can give me some explanation about it.

    (Note: I know GridView is by default horizontally oriented and ListView vertically oriented and that doing the above piece of code on GridView does not make any sense, but it shouldn't impact ContainerContentChanging event behaviour. For my needs I'll use a GridView whitout ItemsPanel set instead of ListView to have horizontally oriented items. But I'm still curious to know why they both behave this way.)


    Monday, September 8, 2014 8:01 AM
  • Hi,

    I think you should use ItemsStackPanel rather than StackPanel. Please try the code below:

                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <ItemsStackPanel Orientation="Horizontal"></ItemsStackPanel>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>

    Monday, September 8, 2014 9:24 AM
  • Thanks jackafx,

    Using ItemsStackPanel on ListView works (ContainerContentChanging is called).

    Then, why StackPanel was accepted by the ItemsPanelTemplate (does not raise any exception) if it does interfere with ListView.ContainerContentChanging behavior?

    I don't get it.

    Plus, ContainerContentChanging still doesn't work when using VariableSizedWrapGrid on GridView.

    Monday, September 8, 2014 9:47 AM
  • Hi,

    I´m not 100% sure but from my understanding ContainerContentChanging only gets fired when the ItemsPanel supportes UI Virtualisation by implementing the IScrollInfo Interface. StackPanel does not implement that Iterface.


    lh

    Monday, September 8, 2014 4:52 PM
  • Thanks Lars,

    That would make sense, as this would be the difference between ItemsStackPanel and StackPanel. ContainerContentChanging providing both the "item" changed and the corresponding "item container", I'm not that surprised ContainerContentChanging is not fired if it cannot get a proper "item container" to pass as parameter.

    So, based on this theory, it would means that the same kind of issue occurs with GridView using VariableSizedWrapGrid. But, I don't any other way to change GridView orientation... Is there something better than VariableSizedWrapGrid I could use to change GridView orientation and get ContainerContentChanging fired?


    Many thanks for your time, both of you, this really helps me understand logic behind it.

    Tuesday, September 9, 2014 6:14 AM