Pregunta

Estoy usando un ListView para mostrar elementos de una lista. El usuario puede seleccionar los elementos a sí mismo, o utilizar algunas teclas de preselección '' para seleccionar elementos con los atributos especificados.

Para comprobar los elementos que utilizo algo así:

for(int i;i<MyListView.Items.Count;++i)
{
    if( /*... Check if the items should be selected ...*/ )
        (MyListView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem).IsSelected = true;
}

Esto funciona perfectamente para los artículos, que son visibles en el momento de excecution. Pero para los artículos, que no son visibles, ContainerFromIndex () devuelve un valor nulo. He oído que esto tiene algo que ver con la virtualización, y que la lista no sabe acerca de los elementos alza oa la baja el 'campo de visión'. Pero, ¿cómo viene que es posible tener elementos seleccionados en la lista de fuera de juego el 'campo de visión' cuando se selecciona manualmente?

Y cómo hacer un select de un 'campo de visión' artículo fuera? Creo que debe ser posible.

Gracias por cualquier ayuda, Marcas

¿Fue útil?

Solución

Como se ha mencionado, yo creo que el problema es la virtualización de los elementos de ListView. Por defecto, ListView (y ListBox) VirtualizingStackPanel uso como su ItemsPanel para mejorar el rendimiento. Una breve explicación de cómo funciona se puede leer aquí .

Se puede sustituir otro panel, sin embargo. En este caso, intente utilizar un StackPanel normal. Si usted tiene un montón de artículos en el ListView, especialmente si son elementos complejos, el rendimiento puede sufrir un poco.

<ListView>
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

Editar

También puede tratar de solución descrita en este pregunta similar , dependiendo de su modelo. Sin embargo, esto probablemente no va a funcionar para usted.

Otros consejos

Cuando se trata de virtualizar los controles de artículos, un método alternativo para desactivar la virtualización (que en realidad es una característica útil a veces, incluso si interfiere con el correcto funcionamiento de otras partes de la API), es encontrar el VirtualizingPanel y contarla de manera explícita de desplazamiento.

Por ejemplo:

void ScrollToIndex(ListBox listBox, int index)
{
    VirtualizingPanel panel = FindVisualChild<VirtualizingPanel>(listBox);

    panel.BringIndexIntoViewPublic(index);
}

static T FindVisualChild<T>(DependencyObject o) where T : class
{
    T result = o as T;

    if (result != null)
    {
        return result;
    }

    int childCount = VisualTreeHelper.GetChildrenCount(o);

    for (int i = 0; i < childCount; i++)
    {
        result = FindVisualChild<T>(VisualTreeHelper.GetChild(o, i));

        if (result != null)
        {
            return result;
        }
    }

    return null;
}

No soy muy feliz con la necesidad de buscar a través del árbol visual para encontrar el panel, pero no estoy al tanto de cualquier otra manera de conseguirlo, ni para desplazarse a un índice específico cuando se trata de un panel de Virtualización .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top