2010-02-08 11 views
7

Dentro de un control de repetidor, ¿hay alguna manera de desactivar ciertos elementos antes de que se muestre la página?Control de repetidor - Cancelar enlace para el elemento específico

Actualmente tenemos una colección de artículos vinculados a un repetidor y si el artículo no forma parte del idioma actual, lo ocultamos.

Estoy esperando poder contar con el repetidor y recuperar un número válido. Un recuento que tampoco incluye los elementos ocultos.

¿Es posible desvincular elementos específicos quizás en el evento ItemDataBound?

actualización

Para cada elemento de la colección que estamos vinculante, comprobamos la base de datos durante la ItemDataBound para más información sobre el tema, tales como el lenguaje, etc. Esto está actualmente nos impide la filtración de la cota datos antes de vincularlo.

Respuesta

2

Acepto las otras respuestas: la mejor solución (tanto para el rendimiento como para la claridad del código) es rediseñar la página para que pueda filtrar las entradas no válidas antes de databinding.

La mayoría de las fuentes de datos no nos permiten eliminar sus elementos mientras ASP.NET los itera. Por ejemplo, si se vincula a un simple genérico List<T>, y elimina un elemento mientras lo itera, la lista lanzará un InvalidOperationException.

En otros casos, ASP.NET realmente itera una copia de la fuente de datos. Si se vincula a un DataTable, ASP.NET usa una copia del contenido (el DataView predeterminado) en lugar de iterar las filas de origen por sí mismas: puede eliminar elementos de la fuente de datos subyacente al iterar, pero no afecta la operación de enlace de datos .

Si filtrar los elementos de antemano realmente no es una opción, su solución actual está bien: ¡simplemente oculte los artículos! Si usted necesita para obtener el recuento correcto encima de eso, realizar un seguimiento del número de elementos no válidos en el controlador ItemDataBound y exponerlo como una propiedad a nivel de página:

if (IsInvalid(args.Item.DataItem)) { 
    this.invalidItemCount++; 
    // code to hide the current item 
} 
+0

Me encantaría rediseñar la forma en que funcionan las páginas, pero estamos usando EPiServer como el CMS y, hasta donde he encontrado, el actual es lo mejor que he podido encontrar. Actualmente estoy siguiendo su última sugerencia para exponer una propiedad Count e incriminarla para artículos válidos. Podría tener que quedarse con eso. Gracias por la respuesta :) –

3

Una solución más adecuada podría ser filtrar la colección enlazada si no hay una necesidad específica en esos elementos ocultos. Algo así como

items.Where(i => i.IsInLanguage(currentLanguage)); 

Actualización:

lo que a mí me gustaría usar este enfoque:

var items = db. 
     Where(i => i.IsInLanguage(currentLanguage)). 
     Where(i => i.SomeField == anotherFilterParameter); 

repeater.DataSource = items; 
repeater.DataBind(); 

Así que todo el filtrado se aplica de antemano

Esto reducirá el número de redonda viajes a la base de datos también, que juega para un mejor rendimiento

+0

Actualizaré mi OQ pero, básicamente, no sabemos qué elementos establecer como visibles, etc. hasta el evento ItemDataBound. Cada elemento tiene una identificación y vamos a la base de datos para obtener detalles adicionales en ese momento. –

+0

¿Qué sucede en ItemDataBound que hace que el filtrado sea posible? ¿Está disponible su idioma actual solo en ese momento? –

+0

sí. Básicamente tenemos algo llamado una colección de ID de "página" y como cada artículo está vinculado, vamos a la base de datos, descubrimos si es parte del idioma actual y si no, ocultamos el artículo. –

2

¿Por qué no filt? er el origen de datos antes de enlazar. Así que asumiendo que usted está utilizando algunos objetos personalizados:

myRepeater.DataSource=repository.getItems().Where(item=>item.Language==CurrentLanguage); 

Si no los necesita no se unen a ellos en primer lugar.

actualización

Si es del todo posible se debe tirar de PROBally esa información por adelantado de la DB. ¿Son estas listas grandes? Si es así, pulsar el db una vez para cada elemento de la lista aparecerá como un problema de rendimiento.

2

La respuesta es muy fácil que acaba de establecer la Visible propiedad a false en el artículo y no se representará. En este ejemplo estoy quitando elementos de una lista de productos que sólo están disponibles para nuevos clientes si el usuario actual tiene un historial de compras:

void rpt_ItemDataBound(object sender, RepeaterItemEventArgs e) 
     { 
      if (!userHasPurchaseHistory) { return; } 
      // filter out products only allowed for new members 
      if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) 
      { 
       System.Data.Common.DbDataRecord rec = (System.Data.Common.DbDataRecord)e.Item.DataItem; 
       if (rec != null) 
       { 
        bool newMemberOnly = Convert.ToBoolean(rec["NewMemberOnly"]); 
        if (newMemberOnly) { e.Item.Visible = false; } 
       } 
      } 

     } 

Tenga en cuenta que lo anterior está enlazado a datos a un IDataReader, puede que tenga que emitir e.Item.DataItem a un objeto diferente dependiendo de a lo que se enlace.

Tenga en cuenta también que definitivamente nunca haría otra búsqueda de base de datos mientras se vincula, nunca debe acceder a la base de datos en un bucle, pero mientras los datos estén vinculados tiene algo que puede verificar para decidir si desea mostrar no hay nada de malo en filtrar en ItemDataBound. Podría ser problemático si está haciendo cualquier tipo de paginación, ya que eso haría que los tamaños de página fueran inconsistentes.

Cuestiones relacionadas