Tengo un enlace de datos configurado con un convertidor para transformar una fuente XML incómoda en un árbol de clases internas de visualización y edición. Todo funciona muy bien para leer desde el origen XML, pero me está costando muchísimo intentar que los cambios realizados en las clases internas se propaguen nuevamente a la fuente XML.Enlace de datos bidireccional con el convertidor no actualiza la fuente
Aquí está el XAML para el sitio de uso:
<local:SampleConverter x:Key="SampleConverter" />
<Expander Header="Sample" >
<local:SampleControl
Sample="{Binding Path=XmlSource,
Converter={StaticResource SampleConverter},
Mode=TwoWay}" />
</Expander>
XmlSource es un CLR lectura y escritura de propiedad (no DependencyProperty) de los datos de los padres objeto dependiente. Es un tipo .NET generado desde un XSD.
SampleConverter implementa IValueConverter
. Se llama al método Convert
y devuelve datos no nulos, pero nunca se llama al método ConvertBack
.
SampleControl es un UserControl que encapsula la interacción de UI con el árbol de datos de muestra. Se XAML se ve así:
<UserControl x:Class="SampleControl">
[... other stuff ...]
<UserControl.Content>
<Binding Path="Sample" RelativeSource="{RelativeSource Mode=Self}" Mode="TwoWay" TargetNullValue="{StaticResource EmptySampleText}" />
</UserControl.Content>
<UserControl.ContentTemplateSelector>
<local:BoxedItemTemplateSelector />
</UserControl.ContentTemplateSelector>
</UserControl>
La propiedad de la muestra es una propiedad de dependencia en el código SampleControl atrás:
public static readonly DependencyProperty SampleProperty =
DependencyProperty.Register("Sample", typeof(SampleType), typeof(SampleControl), new PropertyMetadata(new PropertyChangedCallback(OnSampleChanged)));
public SampleType Sample
{
get { return (SampleType)GetValue(SampleProperty); }
set { SetValue(SampleProperty, value); }
}
private static void OnSampleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != null)
{
((INotifyPropertyChanged)e.NewValue).PropertyChanged += ((SampleControl)d).MyPropertyChanged;
}
else if (e.OldValue != null)
{
((INotifyPropertyChanged)e.OldValue).PropertyChanged -= ((SampleControl)d).MyPropertyChanged;
}
}
private void MyPropertyChanged(object sender, PropertyChangedEventArgs e)
{
; // breakpoint here shows change notices are happening
}
Las clases internas que la XmlSource se convierte a aplicar INotifyPropertyChanged, y están enviando notificaciones de cambio de hasta el árbol, como lo indica un punto de interrupción en MyPropertyChanged arriba.
Entonces, si los datos indican que ha cambiado, ¿por qué WPF no está llamando al método ConvertBack de mi convertidor?
El ejemplo de código para el cambio de propiedad sólo indica que las propiedades de la muestra están cambiando, y no la propia muestra. – Ragepotato
@Ragepotato: ¿Está diciendo que el enlace de datos solo funciona si se asigna una nueva instancia a la propiedad Sample, pero no si las propiedades de la instancia existente a la que hace referencia la propiedad Sample cambian y notifican sus cambios a través de INotifyPropertyChanged? – dthorpe
Sí. La muestra nunca cambió. Es el mismo objeto. Las propiedades dentro de esto cambiaron. Puede probar esto. Ponga un botón en su control después de que todo esté cargado y Sample obtenga su asignación inicial de su máquina virtual. Luego asigne la muestra a un nuevo SampleType. Recuerde que tiene que ser el tipo correcto o el motor de enlace lo ignorará. Si configura su enlace bidireccional a la derecha, verá que se llama su convert devuelta. – Ragepotato