Saltar al contenido

Con enlaces compilados (x: bind), ¿por qué tengo que llamar a Bindings.Update ()?

Si encuentras algún fallo en tu código o trabajo, recuerda probar siempre en un entorno de testing antes subir el código al proyecto final.

Solución:

A veces, los datos que desea mostrar no están disponibles (como los devueltos desde el servidor o la base de datos) hasta varios segundos después de que su página se haya cargado y procesado. Esto es especialmente true si llama a sus datos en un proceso en segundo plano / asíncrono que libera su interfaz de usuario para que se procese sin bloquearse.

¿Tiene sentido hasta ahora?

Ahora cree un enlace; digamos algo como esto:


El valor de su propiedad ViewModel en su código subyacente tendrá un valor real y se vinculará sin problemas. Su usuario, por otro lado, no tendrá un valor porque aún no lo devuelve el servidor. Como resultado, no se puede mostrar ni eso ni la propiedad FirstName del usuario, ¿verdad?

Entonces sus datos se actualizan.

Pensaría que su enlace se actualizaría automáticamente cuando establezca el valor del objeto Usuario en un objeto real. Especialmente si se tomó el tiempo para convertirlo en una propiedad INotifyPropertyChanged, ¿verdad? Eso sería true con Binding tradicional porque el modo de enlace predeterminado es OneWay.

¿Qué es el modo de enlace OneWay?

El modo de enlace OneWay significa que puede actualizar las propiedades de su modelo de backend que implementan INotifyPropertyChanged y el elemento de la interfaz de usuario vinculado a esa propiedad reflejará el cambio de datos / valor. Es maravilloso.

Por que no funciona?

NO es porque x: Bind no es compatible con Mode = OneWay, es porque está predeterminado en Mode = OneTime. En resumen, el Binding tradicional se establece de forma predeterminada en Mode = OneWay y el x: Bind compilado se establece de forma predeterminada en Mode = OneTime.

¿Qué es el modo de enlace OneTime?

El modo de enlace OneTime significa que se enlaza al modelo subyacente solo una vez, en el momento de cargar / renderizar el elemento de la interfaz de usuario con el enlace. Esto significa que si sus datos subyacentes aún no están disponibles, no puede mostrar esos datos y una vez que los datos están disponibles, no los mostrará. ¿Por qué? Porque OneTime no monitorea INotifyPropertyChanged. Solo lee cuando se carga.

Modos (de MSDN): para enlaces OneWay y TwoWay, los cambios dinámicos en la fuente no se propagan automáticamente al destino sin proporcionar algún soporte desde la fuente. Debe implementar la interfaz INotifyPropertyChanged en el objeto de origen para que el origen pueda informar cambios a través de eventos que escucha el motor de enlace. Para C # o Microsoft Visual Basic, implemente System.ComponentModel.INotifyPropertyChanged. Para las extensiones de componentes de Visual C ++ (C ++ / CX), implemente Windows :: UI :: Xaml :: Data :: INotifyPropertyChanged.

¿Cómo resolver este problema?

Hay algunas maneras. El primero y más fácil es cambiar su enlace de ="x:Bind ViewModel.User.FirstName a ="x:Bind ViewModel.User.FirstName, Mode=OneWay. Hacer esto monitoreará los eventos INotifyPropertyChanged.

Este es el momento adecuado para advertirle que el uso de OneTime de forma predeterminada es una de las muchas formas en que x: Bind intenta mejorar el rendimiento del enlace. Eso es porque OneTime es el más rápido posible con la menor cantidad de requisitos de memoria. Cambiar su enlace a OneWay socava esto, pero podría ser necesario para su aplicación.

La otra forma de solucionar este problema y aún mantener los beneficios de rendimiento que vienen con x: Bind es llamar Bindings.Update(); después de que su modelo de vista haya preparado completamente sus datos para su presentación. Esto es fácil si su trabajo es asincrónico, pero, como en el ejemplo anterior, si no puede estar seguro de que un temporizador podría ser su única opción viable.

Eso apesta, por supuesto, porque un temporizador implica la hora del reloj, y en dispositivos lentos como un teléfono, es posible que esa hora no se aplique correctamente. Esto es algo que todo desarrollador tendrá que resolver de forma específica para su aplicación, es decir, ¿cuándo estarán tus datos completamente cargados y listos?

Espero que esto explique lo que está sucediendo.

¡La mejor de las suertes!

Mientras que los enlaces “tradicionales” son por defecto “unidireccionales” (o bidireccionales en algunos casos), los enlaces compilados son “únicos”. Simplemente cambie el modo al configurar el enlace:


Finalmente encontré el error yo mismo: estaba usando una operación basada en tareas para cargar mi modelo de vista, lo que resultó en establecer la propiedad de dependencia por el hilo incorrecto (creo). Funciona si configuro el Instance propiedad a través del despachador.

    public Task Load() 
        return Task.Delay(1000).ContinueWith((t) => 
            var person = new Person()  Name = "Sample Person" ;
            Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
            () => 
                this.Instance = person;
            );                
        );
    

Pero no hubo excepción, ¡solo la interfaz gráfica de usuario no mostraba ningún valor!

Valoraciones y comentarios

Si te ha resultado de ayuda este post, sería de mucha ayuda si lo compartieras con otros juniors y nos ayudes a extender nuestro contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *