Madhur Ahuja
Madhur Ahuja

Reputation: 22701

ItemContainerGenerator.ContainerFromItem returns null for last few items

In the code below, in ColumnsListBox_Loaded event, this method returns null for last few ListBox items. Any idea why is it happening ? I am data binding the listbox in OnOpned() event of ChildWindow class and then retrieving these items in Loaded() event of ListBox class.

  public partial class SPListColumns : ChildWindow
    {
        Web site;
        List spList;
        ListItemCollection listItems;
        string listName;
        public DataGrid MainGrid;

        public SPListColumns(string listName, DataGrid MainGrid)
        {

            InitializeComponent();
            if (!string.IsNullOrEmpty(listName))
            {
                this.listName = listName;

            }

            this.MainGrid = MainGrid;
        }

        void ColumnsListBox_Loaded(object sender, RoutedEventArgs e)
        {

            foreach (DataGridTextColumn columnValue in ColumnsListBox.Items)
            {

                ListBoxItem li = ColumnsListBox.ItemContainerGenerator.ContainerFromItem(columnValue) as ListBoxItem;
                if (li != null)
                {

                    if (MainGrid.Columns.First(s => s.Header == columnValue.Header).Visibility == System.Windows.Visibility.Collapsed)
                    {
                        li.IsSelected = false;
                    }
                    else
                    {
                        li.IsSelected = true;
                    }

                }

            }
        }

        protected override void OnOpened()
        {
            base.OnOpened();
            ColumnsListBox.Loaded += new RoutedEventHandler(ColumnsListBox_Loaded);
            BindColumns(listName);
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;



            foreach (DataGridTextColumn columnValue in ColumnsListBox.Items)
            {

                ListBoxItem li = ColumnsListBox.ItemContainerGenerator.ContainerFromItem(columnValue) as ListBoxItem;
                if (li != null)
                {
                    if (!li.IsSelected)
                    {
                        MainGrid.Columns.First(s => s.Header == columnValue.Header).Visibility = System.Windows.Visibility.Collapsed;
                    }
                }

            }

        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }

        private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }

        private void BindColumns(string listName)
        {

               ColumnsListBox.Items.Clear();
               ColumnsListBox.ItemsSource = MainGrid.Columns;
        }
    }

Upvotes: 1

Views: 1248

Answers (1)

Nicholas W
Nicholas W

Reputation: 2241

The ListBox may be using virtualization to avoid generating containers for items that are not displayed (which would be why the first items work fine for you).

See these answers.

You might want to only look at containers for items that are visible; or inherit ListBoxto override PrepareContainerForItemOverride to access the container as it's (re)used if you want to do something on the fly; or turn off virtualization (change the ItemsPanel to a StackPanel rather than VirtualizingStackPanel).

Upvotes: 1

Related Questions