2010-12-10 9 views
6

Tengo problemas con un convertidor que estoy usando para convertir una cadena en nuestro formato de tiempo. El propio convertidor funciona bien y está implemeneted así:usando IValueConverter con DataContext actual en enlace bidireccional

[ValueConversion(typeof(string), typeof(SimpleTime))] 
    public class StringToSimpleTimeConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      // convert from string to SimpleTime and return it 
     } 
     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      // convert value from SimpleTime to string and return it 
     } 
    } 

el XAML que utiliza el convertidor incluye el propio convertidor en los usercontrol.resources así:

<converter:StringToSimpleTimeConverter x:Key="stringToSimpleTimeConverter"/> 

Si se encuentra la propiedad (I 'm usando la cuadrícula de datos del kit de herramientas de WPF en el fondo) DataTemplate para la edición del simpletime se utiliza:

<DataTemplate x:Key="SimpleTimeEditingTemplate"> 
     <TextBox Text="{Binding, Converter={StaticResource stringToSimpleTimeConverter}, Mode=TwoWay}"/> 
</DataTemplate> 

el problema que estoy encontrando es que el aire verter necesita tener una ruta especificada en el enlace si se trata de un convertidor de dos vías (y lo necesito en ambas direcciones), pero la propiedad que quiero establecer ya es el DataContext actual. ¿Qué camino puedo especificar para eso?

La única solución que se me ocurre es introducir una propiedad ficticia en el SimpleTime que solo obtiene el SimpleTime actual o lo establece.

public class SimpleTime 
{ 
    ... 
    public SimpleTime Clone 
    { 
     get { return new SimpleTime(_amount, _format); } 
     set { this._amount = value._amount; this._format = value._format; } 
    } 
} 

y obligar a que una vía

<TextBox Text="{Binding Clone, Converter={StaticResource stringToSimpleTimeConverter}, Mode=TwoWay}"/> 

que funciona bien, pero no es realmente una solución adecuada, especialmente si necesito convertidores para más veces ...

cualquier ayuda es apreciado vítores, manni

Respuesta

5

Creo que se puede solucionar como este

<TextBox Text="{Binding Path=DataContext, 
         RelativeSource={RelativeSource Self}, 
         Converter={StaticResource stringToSimpleTimeConverter}, 
         Mode=TwoWay}"/> 
+0

He intentado un enfoque similar utilizando un control de usuario padre para el cuadro de texto y vinculante a su contexto de datos. El IValueConverter se llama correctamente para convertir la cadena en simpletime y volver para mostrar la cadena en el control, pero nunca se llama al conjunto de la propiedad simpletime en la estructura de datos. ¿Alguien sabe cómo puede suceder esto? – manni

+0

@manni: Hice una aplicación de prueba con esto y para mí parece estar funcionando bien. Se une a su propio DataContext así que no veo ninguna razón para que no funcione. ¿Estás seguro de que tu método ConvertBack nunca se llama? –

+1

gracias por el esfuerzo. Creo que lo que quiero decir no fue lo suficientemente claro: se llaman mis métodos de conversión y conversión si cambio el valor en la interfaz gráfica de usuario, eso está funcionando bien. pero no se llama a la propiedad setter de la propiedad que estoy configurando (la propiedad simpletime) (no se desencadena el punto de interrupción). Echaré un vistazo a eso ahora, muchas gracias por su ayuda, realmente aprecio que – manni

0

En lugar de introducir una propiedad ficticia en su clase, ¿por qué no crear una clase de contenedor como la siguiente:

public class Container 
{ 
    public Object DataItem { get; set; } 

    //... 
} 

y usarlo como:

<TextBox Text="{Binding DataItem, Converter={StaticResource stringToSimpleTimeConverter}, Mode=TwoWay}"/> 

Esta voluntad no corruptos/mutar su clase existente y todavía le permiten hacer lo que desea hacer.

+0

buena idea, pero no es realmente factible para mis estructuras de datos. No quiero poner cada propiedad en un contenedor, y el objeto List primario está directamente vinculado a la cuadrícula de datos, que elige para cada una de las propiedades de la clase una columna para mostrar y editar, que tendrá la propiedad directamente como datacontext . – manni

+1

Creo que lo que está haciendo es establecer cada propiedad como 'DataContext' de un' Control' y unirlas usando '{Binding}' sin especificar una ruta. Si esto es lo que estás haciendo, está mal. Debe establecer 'DataContext' de un control primario y todos los controles secundarios lo derivan. Y solo usa enlaces usando diferentes rutas en los controles secundarios. – decyclone

+0

pensé que los datagridcolumns funcionaban de esa manera. la plantilla de datos que utilizo para una cuadrícula en la cuadrícula de datos para mostrar o editar no puede tener el contexto de datos establecido en la estructura completa, porque eso significa que ahora debe tener el nombre del atributo al que debe aplicarse. lo que quiero es aplicar la plantilla de datos al tipo específico sin saber su nombre, por lo que mi código establece el enlace para la columna de cuadrícula de datos y establece sus plantillas de datos para mostrar y editar. la plantilla de datos en sí misma se aplica a más de un nombre de propiedad, dependiendo de los tipos de las propiedades – manni

Cuestiones relacionadas