2008-08-27 38 views
6

Estoy desarrollando una aplicación de Windows Forms (.Net 3.5, sin WPF) donde quiero ser capaz de mostrar las búsquedas de clave externa en un DataGridView de enlace de datos.WinForms enlace de datos y relaciones de clave externa

Un ejemplo del tipo de relación es que tengo una tabla de líneas de pedido. Las líneas de pedido tienen una relación de clave externa con productos y productos que a su vez tienen una relación de clave externa con los tipos de productos.

Me gustaría tener un DataGridView enlace de datos donde cada fila representa una Línea de orden, mostrando los productos y Producttype de la línea.

Los usuarios pueden agregar o editar líneas de pedido directamente a la cuadrícula y elegir el producto para la línea de pedido de una comboBoxColumn; esto debería actualizar la columna producttype, mostrando el tipo de producto para el producto seleccionado, en la misma fila.

Lo más cercano a un buen ajuste que he encontrado hasta ahora es introducir un objeto de dominio que representa un OrderLine luego obligar a la DataGridView a una colección de estos OrderLines. A continuación, agrego propiedades al objeto de la línea de pedido que exponen el producto y el tipo de producto, y realizo cambios notorios en los eventos modificados para mantener todo actualizado. En mi repositorio de orderline puedo luego conectar las asignaciones entre este objeto de orden y las tres tablas en mi base de datos.

Esto funciona para el lado de enlace de datos de las cosas, pero tener a mano el código todo lo que O-asignación en el depósito parece mal. Pensé que nHibernate sería capaz de ayudar con este cableado pero estoy luchando con las asignaciones a través de todas las claves externas; parecen funcionar bien (la búsqueda de claves externas para un producto de línea de pedido crea el objeto de producto correcto basado en la clave externa) hasta que intente hacer el enlace de datos, no puedo obtener las columnas de ID de datos para actualizar mi producto o los tipos de productos.

¿Mi enfoque general está en el estadio correcto? Si es así, ¿cuál es una buena solución para el problema de mapeo?

O, ¿hay una mejor solución a las filas de enlace de datos, incluyendo las búsquedas de clave externa que ni siquiera he considerado?

Respuesta

2

Creo que el problema que tienes es que cuando estás enlazando a una grilla, no es suficiente para admitir INotifyPropertyChanged, pero tienes que activar los eventos ListChanged en tu implementación IBindingList y asegurarte de anular y devolver verdadero para la propiedad SupportsChangeNotification. Si no devuelve verdadero para esto, la cuadrícula no lo buscará para saber si los datos han cambiado.

En .NET 2.0+, puede crear una colección genérica usando la clase BindingList, esto se encargará de la mayor parte de la maldad (simplemente no olvide sobrescribir y devolver verdadero para la propiedad SupportsChangeNotification).

Si la clase que utiliza para el enlace de datos tiene una propiedad que es una colección (como IBindingList o BindingList), puede vincular directamente la cuadrícula de la clave externa a esa propiedad.Cuando configura los enlaces en el diseñador de formularios, simplemente seleccione la propiedad de colección como fuente de datos para la cuadrícula. Debería "solo funcionar". La única parte furtiva es asegurarse de manejar las colecciones vacías o nulas de la manera correcta.

+0

Gracias Garo - eso cubre muy bien lo que he encontrado. La única diferencia es que tengo una columna de clave externa, no una grilla. Voy a actualizar mi respuesta ganada también, dejando en claro exactamente lo que me estaba causando problemas - Creo que las razones por las que originalmente diagnostiqué erróneamente el problema pueden ser útiles –

1

bienvenida a StackOverflow :)

Normalmente lo que se puede hacer es base de la información en el menú desplegable en dos valores ValueMember and DisplayMember.

ValueMember es la fuente del valor de los controles reales (este será el valor clave en la línea de pedido), el miembro de visualización es el valor que se muestra al usuario en lugar del valor (este será el valor FK)

¿No hay alguna razón en particular por la que no pueda devolver todos los datos requeridos y establecer estas propiedades?

0

Mi pregunta original, obviamente, no estaba claro, lo siento por eso.

El problema no era con la vinculación de datos a un DataGridView en general, o con la implementación de un DataGridViewComboBoxColumn, como dicen las personas que respondieron correctamente, que está bien documentado en la web.

El problema que he estado tratando de resolver es con la actualización de propiedades que están perforando a través de las relaciones.

En mi ejemplo de pedidos, cuando cambio el valor de la columna "Producto", la columna "Tipo de producto" no se actualiza, aunque en el código estoy configurando la propiedad y activando el evento NotifyPropertyChanged. (En la depuración voy a todos los lugares correctos)

Después de mucho hurgar, me di cuenta de que esto ni siquiera funcionaba cuando establecí directamente la propiedad "Tipo de producto" del origen de datos, en lugar de configurarlo en el "Producto "setter.

La otra cosa que creo que me tiene de nuevo en el camino correcto es que cuando proporciono una capa de acceso a datos simulada, creada en el formulario principal, todo funciona bien.

Además, cuando copio el IList hecho por nHibernate a una IBindingList, todo vuelve a aparecer bien.

Así el problema es que creo que tengan la rosca y los eventos NotifyPropertyChanged se pierdan cuando se utilizan determinadas fuentes de datos, de cierta manera (Ojalá pudiera ser más definitivo que eso!)

Voy a seguir investigando mejores formas de resolver esto que copiar el IList a la IBindingList - tal vez necesito aprender sobre la clasificación de subprocesos.

Editar

ahora he desarrollado una solución que resuelve el problema y creo que entiendo lo que me estaba confundiendo - básicamente parece que cualquier cosa menos de enlace de datos propiedad básica no juega muy bien para listas que aren' derivado de BindingList: tan pronto como intenté enlazarme con las propiedades que disparaban los eventos NotifyPropertyChanged encadenados, las cosas se volvieron locas y mis eventos se perdieron.

La solución de acceso a datos que tengo ahora está usando una variación del patrón Rob Conery IRepository, devolviendo mis colecciones para vincularlas como una clase personalizada, un SortableBindingLazyList que deriva de BindingList, implementa los métodos Sort Core y también almacena su lista interna como una consulta, retrasando la materialización de la lista.

0

Bueno, no sé si es apoyado por el DataGridView, pero cuando estás haciendo WinForms enlace de datos regular (por ejemplo, a un cuadro de texto normal) se puede utilizar caminos de propiedad para navegar a través de las relaciones de objeto.

Algo como esto:

myTextBox.DataBindings.Add("Text", anOrderLine, "OrderedPart.PartNumber"); 

sería digno de ver si esto funciona en su situación también.

Cuestiones relacionadas