viewmodelbase stacklayout instancelocator ejemplo data content calculated bindingcontext wpf data-binding mvvm navigation

wpf - stacklayout - El enlace de datos WVF MVVM se rompe después de la navegación de la página



xamarin stacklayout content binding (2)

Tengo una página dentro de una aplicación de estilo de navegación WPF que muestra resultados de búsqueda. La página contiene varios controles vinculados a datos. La página en sí funciona bien; realiza la búsqueda y devuelve los resultados. Los controles CheckBox enlazados a datos funcionan correctamente.

Pero si hago clic en un enlace de resultado y luego hago clic en el botón Atrás para volver a la lista de resultados, todos los enlaces de datos de CheckBox.IsChecked están rotos. Otros controles vinculados a datos (ComboBoxes, DatePickers, etc.) continúan funcionando como se esperaba. La vinculación a otras propiedades en el control CheckBox, como IsEnabled , funciona correctamente. Pero el enlace IsChecked permanece roto hasta que actualice la página.

Aquí está el XAML utilizado para uno de mis controles CheckBox:

<CheckBox IsChecked="{Binding IncludeNote}" Content="Note" IsEnabled="{Binding IsBusy, Converter={StaticResource boolNot}}" />

Como puede ver, no hay nada lujoso aquí. Pero después de navegar la aplicación WPF hacia adelante o hacia atrás a la página, el enlace IsChecked se romperá mientras la propiedad IsEnabled continuará funcionando.

¿Que está pasando aqui? ¿Es esto un error?

ACTUALIZACIÓN: después de jugar con algunas alternativas, descubrí que este problema también afecta al control ToggleButton, del cual se deriva CheckBox.

ACTUALIZACIÓN2: Y también está roto para la propiedad TextBox.Text.

¿Hay alguna manera de "actualizar" los enlaces de datos para estos controles? ¿O debería tomar algún otro enfoque para solucionar este problema?


Aparentemente, es un error. Aquí está el informe de error en Microsoft Connect: el enlace no funciona después de la navegación hacia atrás / adelante .

El usuario que informó el error, RQDQ , también mencionó su enfoque para tratar el problema:

La solución alternativa que he encontrado es llamar manualmente a BindingOperations.SetBinding para todos los enlaces en la página durante el evento cargado. Esto parece funcionar ya sea navegando de forma explícita o vía historial (operaciones hacia atrás / adelante).

Esto es solo un problema en WPF4. El enlace de datos funciona como se espera en .NET 3.5.

Espero que Microsoft solucione esto rápidamente. Este es un problema serio para las aplicaciones WPF de estilo de navegación.


Una solución simple es establecer KeepAlive en true y luego, para garantizar que no haya problemas con VIewModel con un estado incorrecto de una carga de página anterior, DataContext se establece en una nueva instancia cada vez en el evento Loaded (es decir, no se enlaza a una instancia) del ViewModel en su diccionario Page.Resources, por ejemplo, ya que se mantendrá).

Un enfoque estándar que utilizamos para vincular la página al modelo de vista es con un comportamiento simple asociado a la página.

public sealed class PageViewModelBehavior : Behavior<Page> { public Type DataType { get; set; } protected override void OnAttached() { this.AssociatedObject.KeepAlive = true; this.AssociatedObject.Loaded += this.AssociatedObjectLoaded; this.AssociatedObject.Unloaded += this.AssociatedObjectUnloaded; base.OnAttached(); } protected override void OnDetaching() { this.AssociatedObject.Unloaded -= this.AssociatedObjectUnloaded; this.AssociatedObject.Loaded -= this.AssociatedObjectLoaded; base.OnDetaching(); } private void AssociatedObjectLoaded(object sender, RoutedEventArgs e) { if (this.DataType == null || !typeof(IPageViewModel).IsAssignableFrom(this.DataType)) { throw new InvalidOperationException("PageViewModelBehavior.DataType is not set. Page: " + this.AssociatedObject.GetType().Name); } this.AssociatedObject.DataContext = Activator.CreateInstance(this.DataType); // TODO: Call load on your page view model etc. } private void AssociatedObjectUnloaded(object sender, RoutedEventArgs e) { // TODO: Call unload on your page view model etc. // Allow the throw-away view model to be GC''d this.AssociatedObject.DataContext = null; } }

Esto garantiza que la página se vuelva a enlazar cada vez que el usuario navegue de regreso a la página. Esto también le permite usar su contenedor IOC favorito para crear ViewModel.