2009-07-19 6 views
7

En serio, parece que cada vez que quiero hacer que mis elementos de interfaz de usuario hablen entre sí, termino codificando un nuevo IValueConverter :(. Alguien me dice que lo estoy haciendo mal, por favor!¿Soy solo yo o WPF es un desastre de enlaces de datos y IValueConverters personalizados?

Ejemplos:

.!

  • quería un botón para habilitar únicamente si mi cuadro de texto contenía una URI válida Genial, es momento de codificar un UriIsValidConverter
  • Ah perdón, quiero también querían desactivarlo mientras estoy procesando algo. Supongo que ahora necesito codificar un UriIsValidAndBoolIsFalseMultiConverter!
  • Quiero t para mostrar una lista de archivos en un directorio determinado (especificado por un cuadro de texto) dentro de un cuadro de lista. ¡Creo que necesito un convertidor DirectoryPathToFileList!
  • Oh hola, quiero iconos para cada uno de esos archivos en la lista. ¡Tiempo para un convertidor FileInfoToBitmap!
  • Quiero que mi estado sea rojo si mi cadena de estado contiene "Error", y verde de lo contrario. ¡Sí, tengo que codificar un StatusStringToSolidColorBrushConverter!

Realmente estoy pensando que esto no es mucho mejor que el antiguo método de Windows Forms de simplemente conectar todo manualmente usando eventos TextChanged (o lo que sea). Lo cual supongo que todavía es una opción. ¿Es eso lo que la gente realmente hace, tal vez, y estoy tratando demasiado para que todo encaje en el paradigma de la vinculación de datos?

Así que sí, por favor díganme si esta es realmente la forma en que WPF es la codificación --- o si lo estoy haciendo mal, y si es así, lo que debería estar haciendo.

+0

Más cerca probablemente respondía al nivel de frustración en la pregunta de este tipo. La forma en que lo haces parece muy frustrante. Es por eso que debes verificar MVVM. Toma la frustración directamente. – Will

Respuesta

10

Su enfoque es perfectamente válido (aunque usaría una multienlace para el segundo ejemplo, en lugar de un convertidor especializado), aunque al colocar toda su lógica en el XAML está produciendo un acoplamiento muy alto entre la forma en que se ve y la forma en que se comporta, debido a esto es posible que desee examinar el patrón MVVM para separar esas cosas.

Bajo el patrón MVVM su XAML (la vista) solo contiene enlaces de datos muy simples en un ViewModel que maneja toda la lógica y actualiza la vista a través de la interfaz INotifyPropertyChanged. El código para su tercer ejemplo podría ser algo como:

public class DirectoryManagerViewModel : INotifyPropertyChanged 
{ 
    private string _directory; 

    public string Directory 
    { 
     get { reutrn _directory; } 
     set 
     { 
      if (_directory != value) 
      { 
       _directory = value; 
       OnPropertyChanged("Directory"); 
       if (IsValidDirectory(value)) 
       { 
        PopulateFiles(); 
       } 
      } 
     } 
    } 

    public ObservableCollection<FileViewModel> Files { get; private set; } 

    private bool IsValidDirectory(string directory) 
    { 
      //return if the directory exists etc. 
    } 

    private bool PopulateFiles() 
    { 
     //Populate Files with files in directory 
    } 
} 

Dónde FileViewModel es otro modelo de vista que contiene el nombre y el icono de un archivo.

La ventaja de este enfoque es que los ViewModels se pueden reutilizar con otras vistas y otras tecnologías como ASP.NET o Winforms para que no esté bloqueado en la pila de WPF. (alos si trabajas en un entorno donde hay diseñadores responsables del aspecto y desarrolladores responsables del comportamiento, esto ayuda a definir esos límites)

Al final del día, aunque esta lógica necesita ir a algún lado y mientras está allí son mejores y peores maneras de diseñar su aplicación, usted todavía va a escribir código que toma una cadena y la convierte en una serie de nombres de archivos e iconos en alguna parte.

+0

MVVM es la respuesta a los problemas de este tipo. Lógica para la validación y activarla y desactivarla en ViewModel. – Will

+0

¡Gracias y los otros que responden también! Miré a MVVM cuando comencé, y, bueno, me asusté por la complejidad. Pero su ejemplo fue realmente útil para ver solo lo básico y convencerme de que lo intente de nuevo. Tu punto acerca de que el código tiene que ir a alguna parte también está bien. – Domenic

6

En primer lugar, es posible que desee comenzar por leer sobre el Model-View-ViewModel pattern (MVVM). Josh Smith tuvo un fantástico article en MSDN Magazine recientemente. MVVM y WPF van perfectamente juntos. Hecho bien, no lo hará need IValueConverters so much.La forma en que lo está haciendo ahora está causando un acoplamiento muy apretado entre su visualización y las acciones de su aplicación. MVVM está diseñado para desacoplar estos elementos.

En este contexto, su modelo de vista rastreará el estado por usted. Su botón se habilitará si el método CanExecute en un cierto ICommand en su modelo de vista devuelve verdadero. Este mismo concepto puede manejar deshabilitar el botón cuando se procesa algo.

¿Desea visualizar una lista de archivos en un determinado directorio que se especifica dentro de un cuadro de lista? Tenga un modelo de vista DirectoryViewModel que se encargará de proporcionar la lista de archivos vinculados al modelo de vista. La visualización de los archivos se puede especificar con un DataTemplate especificado en XAML sin código. Este mismo concepto puede manejar proporcionar los iconos a la vista cuya visualización se puede especificar en la plantilla.

¿Desea que su estado sea rojo si un mensaje de estado contiene "Error" y verde de lo contrario? Deje que un modelo de vista maneje la determinación del estado y permita que la vista se vincule a ese estado y ahora solo necesita un IStateConverter para convertir el estado a rojo o verde de manera apropiada (esta es una de las muchas maneras de manejar este problema en el contexto de MVVM).

Acostúmbrese a mantener los datos y el estado separados de su vista y sus aplicaciones se acoplarán de forma flexible, serán más fáciles de diseñar y mantener, y más fáciles de probar.

5

No sé si estás equivocado, simplemente haciéndolo mucho más difícil de lo que tiene que ser.

Uso MVVM, por lo tanto, cuando escribe convertidores de clientes, proporciono una propiedad enlazable en el modelo de vista que le dice a la vista qué hacer. Por ejemplo:

  1. Para mostrar una lista de archivos, proporciono una colección que contiene esa lista.
  2. Si quiero iconos del objeto en esa colección tiene un icono de la propiedad
  3. Si quiero un estado de ser de color rojo o verde que proporciono una propiedad StatusColorbrush.

Moviendo esta lógica en el modelo de vista, me sale:

  1. mucho más simple Xaml.
  2. puede probar mi lógica de vista sin la vista.

Este enfoque utiliza uno de los puntos fuertes de WPF, sus capacidades vinculantes.

Cuestiones relacionadas