2012-05-18 6 views
5

Entonces, tengo una tabla de clientes, que contiene registros de clientes, registro, cada uno de los cuales tiene un campo de tipo de campo. También tengo una tabla customertype, que contiene los valores válidos para el campo customertype.WPF/XAML - Permitir que ComboBox tenga SelectedValue que no esté en ItemsSource

Y necesito un WPF para hacer CRUD. (Crear, revisar, actualizar, eliminar).

La solución obvia es utilizar un ComboBox, con su propiedad SelectedValue vinculada al campo customertype, y su propiedad ItemsSource vinculada a una lista poblada por una consulta de la tabla customertype.

El problema es que esto no funciona, excepto en el tipo de problema simple que se ve en los ejercicios.

La dificultad surge cuando está viendo o editando un registro de cliente que tiene un valor de tipo de dominio que no está en la tabla de tipos de elemento. Esto puede suceder por error, o puede suceder porque el tipo de elemento principal se ha desaprobado y eliminado de la tabla.

Lo que hace WPF, en esta circunstancia, es establecer el campo tipo de elemento de comando en nulo, porque SelectedValue no está en la lista ItemsSource. Y eso es un problema

Si solo está viendo, debería ver el valor que está en la tabla, independientemente de si está en la lista. Si está editando, puede hacer un argumento razonable de que también debe mostrar el valor que está en la tabla, al menos inicialmente, aunque si cambia la selección, no puede obtener lo que comenzó.

¿Alguna idea? Este es un problema que ocurre en casi todos los formatos de edición/vista que tengo, por lo que preferiría algo que esté razonablemente limpio en el momento del uso. (Es decir, dada la elección de la complicación en el XAML, cada lugar que necesito para manejar uno de estos campos, o una complicación en el código que respalda el XAML que inserto para manejar uno de estos campos, prefiero este último)

Respuesta

3

Para esto, le sugiero que no vincule su ItemsSource directamente al contenido de la tabla CustomerType. En su lugar, combine un ItemsSource para elementos de tipo de cliente en las tablas de tipo de cliente Y todos los valores de tipo de cliente almacenados en registros de cliente que no existen en la tabla de tipo de cliente. Una vez que el usuario pasa de la visualización a la edición, actualice la colección para usar solo esos elementos en la tabla CustomerType. Cuando el usuario entra en el modo de visualización, vuelve a la colección fusionada.

+0

Lo intento y no funciona del todo. El código que se encuentra detrás de ItemsSource del combobox ahora inserta el customerid actual, si no está en lo que se devuelve desde la base de datos, si estamos viendo un registro existente. Pero si cambio para editar un nuevo registro, estoy levantando PropertyChanged en la propiedad ItemsSource, y en el depurador puedo ver el código llamado, y una nueva lista construida que no incluye el valor extra, sino en la UI, Todavía veo la primera lista. –

+0

¿Ha usado trie utilizando ObservableCollection para su ItemsSource o INotifyPropertyChanged cuando cambia su colección de Lista? – Josh

+0

Sólo un poco de confusión mental de mi parte. No estaba criando cambios de propiedad en la propiedad, pensé que era. –

0

Si bien la respuesta anterior sirve, hace una buena cantidad de código, en cada caso. Y este problema existe como un patrón general, cualquier lugar donde una lista proviene de un lugar y el valor seleccionado proviene de otro.

Todavía no he decidido una solución, pero mi último intento es prometedor.

Lo que he hecho es derivar una nueva clase de ComboBox. Para ello, he agregado una nueva DependencyProperty - AddSelectedIfMissing. Y luego anulo OnItemsChanged(). En él, compruebo si SelectedValue coincide con el campo SelectedValuePath de cualquiera de los elementos en ItemsSource.

Estoy vinculando ItemsSource a una propiedad del modelo de vista que devuelve una colección de objetos de registro que representan opciones válidas. Estoy vinculando SelectedValue a una propiedad del viewmodel que contiene el valor existente. Y estoy vinculando AddSelectedIfMissing a una propiedad booleana del viewmodel que es verdadera cuando deseo agregar SelectedValue a ItemsSource.

Y cuando cambio de vista a edición, levanto PropertyChanged en la propiedad vinculada a ItemsSource, por lo que el control la volverá a cargar.

Lo que tengo ahora tiene algunas limitaciones. Depende de poder convertir ItemsSource de object en IList, y poder convertir cada elemento de objeto en una clase base conocida de la que podamos obtener valores de campo. Y no funcionaría si hubiera vinculado SelectedItem, en lugar de SelectedValue.

Pero dentro de esas limitaciones, funciona bien.

+1

¿Puedes publicar tu código para esto? Me doy cuenta de que es una vieja pregunta, pero tengo un problema similar y me interesaría. – PlTaylor

Cuestiones relacionadas