简体   繁体   中英

WPF Unable to get ListBoxItem by item or by index after 7th item

I'm having a bit of a weird problem where I am trying to update the checked status of a checkbox contained inside a ListBoxItem, I am unable to get a ListBoxItem after the 7th item I've tried several methods to get this to work, as seen in the below method. itemIndex each time does have a positive value (so the I know the item is being found), but why It cant get the listboxitem I do not know

private IEnumerable<CheckBox> GetListBoxItemCheckBoxes(object item)
{
    var itemIndex = LstItems.Items.IndexOf(item);
    var selectedListBoxItem = LstItems.ItemContainerGenerator.ContainerFromIndex(itemIndex) as ListBoxItem;
    var selectedListBoxItemCheckBoxes = selectedListBoxItem?.FindVisualChildrenOfType<CheckBox>();

    if (selectedListBoxItemCheckBoxes == null)
    {
        selectedListBoxItem = LstItems.ItemContainerGenerator.ContainerFromItem(item) as ListBoxItem;
        selectedListBoxItemCheckBoxes = selectedListBoxItem?.FindVisualChildrenOfType<CheckBox>();

        if (selectedListBoxItemCheckBoxes == null)
        {
            itemIndex = LstItems.ItemContainerGenerator.Items.IndexOf(item);
            selectedListBoxItem = LstItems.ItemContainerGenerator.ContainerFromIndex(itemIndex) as ListBoxItem;
            selectedListBoxItemCheckBoxes = selectedListBoxItem?.FindVisualChildrenOfType<CheckBox>();
        }
    }

    return selectedListBoxItemCheckBoxes;
}

I think that this may be to do with the timing of when I am trying to set the checkbox states as I am trying to do it after I have added that item? I've read a few questions relating to this area on SO but so far none of have been able to help me with my problem, I thought this answer might be close.. but It gave me the same result: https://stackoverflow.com/a/23501378/1800140

The items are not bound, they are added using ListBox.Items.Add (not too familiar with binding).

I am also doing this in a background thread as I need to refresh the contents of my listbox regularly and need to make an api call to do so.

The method that is being used for updating the contents of my listbox is as below. SetItemChecked calls the first method to get the checkbox, however this starts to return null after the 7th item

public void ResetAndAddItems<T>(IEnumerable<T> items, string displayByProperty = "",
        Func<T, string> displayByFunc = null,
        Dictionary<string, bool> checkedStates = null,
        Func<ListItem<T>, Dictionary<string, bool>, bool> checkedStatesKeyFunc = null)
{
    Dispatcher.Invoke(() =>
    {
        LstItems.Items.Clear();
    });

    var listedItems = items?.ToList();

    if (listedItems == null || !listedItems.Any())
    {
        return;
    }

    foreach (var item in listedItems)
    {
        var listItem = new ListItem<T>
        {
            DisplayByProperty = displayByProperty,
            DisplayByFunc = displayByFunc,
            Item = item
        };

        Dispatcher.Invoke(() =>
        {
            LstItems.Items.Add(listItem);
            if (checkedStates != null && checkedStatesKeyFunc != null)
            {
                SetItemChecked(item, checkedStatesKeyFunc(item as ListItem<T>, checkedStates));
            }
        });
    }
}

UI Virtualization is set to True by default on ListBoxes. And if UI Virtualization is enabled, containers will only be created for the visible items. Try setting this attached property:

VirtualizingStackPanel.IsVirtualizing="False" 

To fix this issue, I had to result to binding.

The issue is that because only 7 items are display on the listview at once only 7 items are drawn, to get around this I can scroll to the next item after the 7th item and so on however this was noticeably slower.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM