Почему ItemContainerGenerator возвращает ноль? - PullRequest
1 голос
/ 20 июля 2010

У меня есть ListBox, и мне нужно установить его ControlTemplate на Virtualization WrapPanel, который является классом, расширяющим VirtualizingPanel, используя стиль, который выглядит следующим образом:

<Style TargetType="{x:Type ListBox}" x:Key="PhotoListBoxStyle">
                <Setter Property="Foreground" Value="White" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate  TargetType="{x:Type ListBox}" >
                            <s:VirtualizingVerticalWrapPanel>
                            </s:VirtualizingVerticalWrapPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

Теперь в закрытом методеВиртуализация WrapPanel ниже я пытаюсь получить доступ к этому. ЭлементContainerGenerator, но я получаю нулевое значение, любая идея, в чем проблема ??

private void RealizeFirstItem()
{
    IItemContainerGenerator generator = this.ItemContainerGenerator;
    GeneratorPosition pos = generator.GeneratorPositionFromIndex(0);

    using (generator.StartAt(pos, GeneratorDirection.Forward))
    {
        UIElement element = generator.GenerateNext() as UIElement;

         generator.PrepareItemContainer(element);

                    this.AddInternalChild(element);
    }
 }

Ответы [ 5 ]

7 голосов
/ 31 марта 2011

Я думаю, у меня была похожая проблема, и это помогло:

var necessaryChidrenTouch = this.Children;
IItemContainerGenerator generator = this.ItemContainerGenerator;

... по какой-то причине вам нужно «дотронуться» до дочерней коллекции, чтобы ItemContainerGenerator правильно инициализировался.

2 голосов
/ 15 августа 2014

Для приложений Windows 8.1 Metro ItemContainerGenerator был удален и будет возвращать ноль.Новый Apis:

ItemsControl.ItemContainerGenerator.ItemFromContainer = ItemsControl.ItemFromContainer

ItemsControl.ItemContainerGenerator.ContainerFromItem = ItemsControl.ContainerFromItem *tainContain.Conf.Conf.*

ItemsControl.ItemContainerGenerator.ContainerFromIndex = ItemsControl.ContainerFromIndex

http://msdn.microsoft.com/en-us/library/windows/apps/dn376326.aspx

0 голосов
/ 14 января 2016

Скорее всего, это проблема, связанная с виртуализацией, поэтому контейнеры ListBoxItem генерируются только для видимых в данный момент элементов (например, https://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingstackpanel(v=vs.110).aspx#Anchor_9)

. Я бы предложил переключиться на ListView вместо ListBox -он наследуется от ListBox и поддерживает метод ScrollIntoView(), который можно использовать для управления виртуализацией;

targetListView.ScrollIntoView(itemVM);
DoEvents();
ListViewItem itemContainer = targetListView.ItemContainerGenerator.ContainerFromItem(itemVM) as ListViewItem;

(в приведенном выше примере также используется статический метод DoEvents(), более подробно описанный здесь; WPF, как ждать обновления связывания перед обработкой большего количества кода? )

Есть несколько других незначительных различий между элементами управления ListBox и ListView ( В чем разницамежду ListBox и ListView ) - что не должно существенно повлиять на ваш вариант использования.

0 голосов
/ 23 февраля 2014

Falck в основном правильно. На самом деле, вам нужно сослаться на InternalChildren панели виртуализированного стека. Декомпилированный код для этого свойства:

    protected internal UIElementCollection InternalChildren
    {
        get
        {
            this.VerifyBoundState();
            if (this.IsItemsHost)
            {
                this.EnsureGenerator();
            }
            else if (this._uiElementCollection == null)
            {
                this.EnsureEmptyChildren(this);
            }
            return this._uiElementCollection;
        }
    }

«EnsureGenerator» выполняет работу по обеспечению доступности генератора. Очень плохой дизайн «как раз вовремя», ИМО.

0 голосов
/ 31 марта 2011

Это потому, что вы изменили шаблон списка, в то время как вы должны были просто изменить ItemsPanel:

    <ListBox>
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <s:VirtualizingVerticalWrapPanel />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...