Forcing WPF to create the items in an ItemsControl

前端 未结 6 1303
日久生厌
日久生厌 2021-01-12 18:13

I want to verify that the items in my ListBox are displayed correctly in the UI. I figured one way to do this is to go through all of the children of the

6条回答
  •  失恋的感觉
    2021-01-12 18:35

    I think I figured out how to do this. The problem was that the generated items were not added to the visual tree. After some searching, the best I could come up with is to call some protected methods of the VirtualizingStackPanel in the ListBox. While this isn't ideal, since it's only for testing I think I'm going to have to live with it.

    This is what worked for me:

    VirtualizingStackPanel itemsPanel = null;
    FrameworkElementFactory factory = control.ItemsPanel.VisualTree;
    if(null != factory)
    {
        // This method traverses the visual tree, searching for a control of
        // the specified type and name.
        itemsPanel = FindNamedDescendantOfType(control,
            factory.Type, null) as VirtualizingStackPanel;
    }
    
    List generatedItems = new List();
    IItemContainerGenerator generator = this.ItemsListBox.ItemContainerGenerator;
    GeneratorPosition pos = generator.GeneratorPositionFromIndex(-1);
    using(generator.StartAt(pos, GeneratorDirection.Forward))
    {
        bool isNewlyRealized;
        for(int i = 0; i < this.ItemsListBox.Items.Count; i++)
        {
            isNewlyRealized = false;
            UIElement cntr = generator.GenerateNext(out isNewlyRealized) as UIElement;
            if(isNewlyRealized)
            {
                if(i >= itemsPanel.Children.Count)
                {
                    itemsPanel.GetType().InvokeMember("AddInternalChild",
                        BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMember,
                        Type.DefaultBinder, itemsPanel,
                        new object[] { cntr });
                }
                else
                {
                    itemsPanel.GetType().InvokeMember("InsertInternalChild",
                        BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMember,
                        Type.DefaultBinder, itemsPanel,
                        new object[] { i, cntr });
                }
    
                generator.PrepareItemContainer(cntr);
            }
    
            string itemText = GetControlText(cntr);
            generatedItems.Add(itemText);
        }
    }
    

提交回复
热议问题