2013-09-15 8 views
1

Я создаю настраиваемый VirtualizingPanel, который будет использоваться в элементе управления ListBox. Я делаю некоторые тесты, где я столкнулся с проблемой в методеПользовательский VirtualizingPanel: IItemContainerGenerator.IndexFromGeneratorPosition (position) возвращает -1

IItemContainerGenerator.IndexFromGeneratorPosition(position) 

возвращает -1, если я устанавливаю ItemsSource в ListBox в в конструкторе (который до нагруженного события) моего UserControl, где он принимает ListBox , Тем не менее, он не возвращает -1, если я должен установить ListSource ListBox в событие Loaded.

Проблема возникает, когда возникает исключение NullReferenceException при выполнении метода IItemContainerGenerator.Remove (position, offset).

Приведенный ниже код показывает способ, в котором я виртуализировать элементы

private void CleanupItems() 
{ 
    IItemContainerGenerator iGenerator = this.ItemsOwner.ItemContainerGenerator; 

    for (int i = this.InternalChildren.Count - 1; i >= 0; i--) 
    { 

     GeneratorPosition position = new GeneratorPosition(i, 0); 
     int itemIndex = iGenerator.IndexFromGeneratorPosition(position); 

     if (itemIndex < this.StartIndex || itemIndex > this.EndIndex) 
     { 
      iGenerator.Remove(position, 1); 
      this.RemoveInternalChildRange(i, 1); 
     } 

    } 
} 

В настоящее время я положил это (исправить? Взломать?) В конструкторе моего VirtualizingPanel в

Loaded += (s, e) => 
{ 
    if (ItemsOwner.ItemsSource != null) 
    { 
     this.InvalidateMeasure(); 
    } 
}; 

, как я должен решить эту проблему в Правильный способ? какие-либо предложения?

ответ

0

IItemContainerGenerator.IndexFromGeneratorPosition вернет -1, если контейнеры для ваших товаров не будут сгенерированы.

Во время конструктора ваши элементы не отображаются в пользовательском интерфейсе. Следовательно, нет контейнеров, но они доступны после визуализации вашего пользовательского интерфейса. Вот почему вы получаете их после загруженного события.

Вы можете проверить статус своего ItemContainerGenerator, он должен быть ContainersGenerated перед обработкой вашего запроса. Крючок для StatusChanged события

ItemsOwner.ItemContainerGenerator.StatusChanged += (s, args) => 
{ 
    if (ItemsOwner.ItemContainerGenerator.Status == 
         GeneratorStatus.ContainersGenerated) 
    { 
     // Your code goes here.   
    } 
}; 
+0

спасибо за ответ, не могли бы вы объяснить жизненный цикл ItemContainerGenerator? – icube

+0

Ссылка здесь - http://drwpf.com/blog/category/item-containers/ поможет вам понять, как это работает. –

+0

Привет, я все еще сталкиваюсь с этой проблемой. Фактически статус ItemContainerGenerator уже ContainersGenerated, когда я выполняю мой выше метод CleanUpItems() ... поэтому я думаю, что ваш ответ недействителен – icube