c# - ¿Cómo se obtiene el nombre de asignación adecuado de una fuente de enlace vinculada a una Lista<T>, o un tipo anónimo, para usar en un DataGridTableStyle?
compact-framework bindingsource (5)
La consulta devuelve IEnumerable<T>
para algunos T
, pero la mayoría de las fuentes de enlace (excepto ASP.NET) requieren IList
(como cualquier implementación IList<T>
) - intente agregar .ToList()
- es decir
myBindingSource.DataSource = query.ToList();
Una BindingList<T>
podría funcionar aún mejor (si es compatible con CF 3.5) ya que tiene una mejor compatibilidad para algunos de los escenarios de enlace comunes; si necesita esto (y suponiendo que BindingList<T>
existe en CF 3.5), puede agregar un método de extensión:
static BindingList<T> ToBindingList<T>(this IEnumerable<T> data)
{
return new BindingList<T>(new List<T>(data));
}
luego llame:
myBindingSource.DataSource = query.ToBindingList();
Para completar, una alternativa a un IList
es IListSource
(o incluso Type
para escenarios puramente de metadatos), que es la razón por la cual DataSource
comúnmente se tipea como object
; si no fuera por este problema, el compilador probablemente podría haberle indicado el problema (es decir, si DataSource
se definió como IList
).
Estoy intentando crear un objeto DataGridTableStyle para poder controlar el ancho de columna de un DataGrid. Creé un objeto BindingSource vinculado a una lista. En realidad, está vinculado a una lista de tipos anónimos creada a través de Linq de la siguiente manera (los nombres de las variables han cambiado para mayor claridad de lo que estoy haciendo):
List<myType> myList = new List<myType>(someCapacity);
.
...populate the list with query from database...
.
var query = from i in myList
select new
{
i.FieldA,
i.FieldB,
i.FieldC
};
myBindingSource.DataSource = query;
myDataGrid.DataSource = myBindingSource;
Luego creo un objeto DataGridTableStyle y lo agrego a la cuadrícula de datos. Sin embargo, nunca aplica mis propiedades de estilo de tabla que configuré porque no puedo establecer la propiedad adecuada myDataGridTableStyle.MappingName.
He buscado en Google por aproximadamente 1/2 hora y sigo viendo enlaces a la misma pregunta en un montón de foros diferentes (literalmente, el mismo texto, como alguien que acaba de copiar y pegar la pregunta ... Odio eso ...) . De todos modos, ninguna de las sugerencias funciona, al igual que el hombre dice en todos los otros sitios.
Entonces, ¿alguien aquí sabe a qué debo ajustar la propiedad MappingName para que mi TableStyle realmente funcione correctamente? ¿De dónde puedo tomar el nombre? (No puede estar en blanco ... que solo funciona con un BindingSource que está vinculado a un DataTable o SqlCeResultSet, etc.).
Estoy pensando que podría ser un problema utilizar Linq para crear una versión anónima y más especializada de los objetos con solo los campos que necesito. ¿Debo tratar de vincular BindingSource directamente al objeto List? O tal vez incluso unir DataGrid directamente al objeto List y omitir la fuente de enlace por completo.
Gracias
PS - C #, Compact Framework v3.5
ACTUALIZAR:
He publicado una respuesta a continuación que resolvió mi problema. Si es o no el mejor enfoque, funcionó. Vale la pena echar un vistazo si tienes el mismo problema que tuve.
He encontrado la manera de hacer que esto funcione. Lo dividiré en secciones ...
List<myType> myList = new List<myType>(someCapacity);
.
...populate the list with query from database...
.
DataGridTableStyle myDataGridTableStyle = new DatGridtTableStyle();
DataGridTextBoxColumn colA = new DataGridTextBoxColumn();
DataGridTextBoxColumn colB = new DataGridTextBoxColumn();
DataGridTextBoxColumn colC = new DataGridTextBoxColumn();
colA.MappingName = "FieldA";
colA.HeaderText = "Field A";
colA.Width = 50; // or whatever;
colB.MappingName = "FieldB";
.
... etc. (lather, rinse, repeat for each column I want)
.
myDataGridTableStyle.GridColumnStyles.Add(colA);
myDataGridTableStyle.GridColumnStyles.Add(colB);
myDataGridTableStyle.GridColumnStyles.Add(colC);
var query = from i in myList
select new
{
i.FieldA,
i.FieldB,
i.FieldC
};
myBindingSource.DataSource = query.ToList(); // Thanks Marc Gravell
// wasn''t sure what else to pass in here, but null worked.
myDataGridTableStyle.MappingName = myBindingSource.GetListName(null);
myDataGrid.TableStyles.Clear(); // Recommended on MSDN in the code examples.
myDataGrid.TablesStyles.Add(myDataGridTableStyle);
myDataGrid.DataSource = myBindingSource;
Básicamente, DataGridTableStyle.MappingName necesita saber a qué tipo de objeto se está asignando. Como mi objeto es de tipo anónimo (creado con Linq), no sé qué es hasta el tiempo de ejecución. Después de vincular la lista del tipo anónimo al origen de enlace, puedo usar BindingSource.GetListName (null) para obtener la representación de cadena del tipo anónimo.
Una cosa a tener en cuenta. Si acabo de vincular myList (que es tipo "myType") directamente al origen de enlace, podría haber utilizado la cadena "myType" como el valor para DataGridTableStyle.MappingName.
¡Espero que esto sea útil para otras personas!
Seguí esta respuesta y descubrí que MappingName siempre aparecía como el nombre de clase subyacente (myType en el ejemplo).
Por lo tanto, parece que poner la colección a través de BindingSource resuelve el problema de todos modos y que no hay necesidad de BindingSource.GetListName (null).
Además, no encontré necesario ToList () la consulta, ya que BindingSource también lo hará por usted.
Muchas gracias a Jason Down por ponerme en el camino correcto.
Solo para agregar a la colección de respuestas que ya está en esta página ...
Me sentí frustrado con este mismo problema al tratar de desarrollar mi primera aplicación utilizando formularios de Windows y un marco compacto (para Windows Mobile 6.5).
Lo que descubrí, a través del comentario anterior de Marc Gravell, es que de hecho es posible obtener el tiempo de ejecución MappingName inspeccionando las propiedades de DataGrid. Al hacer esto, descubrí que al vincular mi List<MyType>
directamente a la propiedad DataSource de DataGrid, DataGrid estaba realmente buscando un DataGridTableStyle con el MappingName de
"List`1"
en lugar de cualquier combinación de List<MyType>
o MyType
...
Entonces ... al poner "List`1" en el nombre de Mapeo en el Editor de la Colección DataGridTableStyle (en tiempo de diseño), pude personalizar las columnas y otras propiedades sin tener que crearlas todas en tiempo de ejecución.
Solo espero que esto agregue algo más a las respuestas ya proporcionadas. Gracias a todos por proporcionarme las pautas.
Estaba enfrentando el mismo problema para establecer el ancho de la columna. Después de mucho I + D, cambié el código de la siguiente manera y funciona bien. Código:
DataGridTableStyle tableStyle = new DataGridTableStyle();
tableStyle.MappingName = dgCustom.DataSource.GetType().Name;
donde dgCustom
es ID de DataGrid en dgCustom.DataSource.GetType().Name
que funciona perfectamente.