mvvm windows-runtime windows-store-apps winrt-xaml

mvvm - Dónde acceder a DataContext en WinRT XAML UserControl



windows-runtime windows-store-apps (1)

Tengo UserControlViewModel que plantea un evento:

public event EventHandler<EventArgs> StuffDone;

Un objeto de UserControlViewModel se crea e inicializa dentro de MainPageViewModel :

this.userControlViewModel = new UserControlViewModel();

MainPageViewModel es el View-Model para MainPage .

En MainPage.xaml, tengo el siguiente código para colocar UserControlView UserControl en MainPage e inicializar su DataContext :

<views:UserControlView DataContext="{Binding userControlViewModel, Mode=OneWay}" IsHitTestVisible="False"></views:UserControlView>

Hasta ahora todo funciona bien.

Ahora me gustaría suscribirme al evento StuffDone dentro de UserControlView . Lo primero que se me ocurrió es hacerlo dentro del controlador de eventos Loaded de UserControlView ; sin embargo, DataContext en ese punto aún es null . Escanear el resto de los eventos de UserControl no me dio ninguna pista.

Entonces, ¿dónde está el lugar correcto para obtener el DataContext y suscribirse a sus eventos?

Gracias por adelantado.


ACTUALIZACIÓN : el evento DataContextChanged es compatible con WinRT para Windows 8.1. Utilice lo siguiente solo si está codificando contra WinRT para Windows 8 o cualquier plataforma que no admita DataContextChanged .

Parece que no hay una manera directa de hacerlo y la solución sugerida por Will en su comentario es la forma más sencilla de hacerlo.

A continuación se muestra mi versión de la solución alternativa que funciona para mí:

En IDataContextChangedHandler.Generic.cs:

using Windows.UI.Xaml; namespace SomeNamespace { public interface IDataContextChangedHandler<in T> where T : FrameworkElement { void DataContextChanged(T sender, DependencyPropertyChangedEventArgs e); } }

En DataContextChangedHelper.Generic.cs:

using Windows.UI.Xaml; using Windows.UI.Xaml.Data; namespace SomeNamespace { public sealed class DataContextChangedHandler<T> where T : FrameworkElement, IDataContextChangedHandler<T> { private readonly DependencyProperty internalDataContextProperty = DependencyProperty.Register( "InternalDataContext", typeof(object), typeof(T), new PropertyMetadata(null, DataContextChanged)); private static void DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { var control = sender as T; if (control == null) { return; } control.DataContextChanged(control, e); } public void Bind(T control) { control.SetBinding(this.internalDataContextProperty, new Binding()); } } }

En UserControlView.xaml.cs:

using Windows.UI.Xaml; namespace SomeNamespace { public sealed partial class UserControlView : IDataContextChangedHandler<UserControlView> { private readonly DataContextChangedHandler<UserControlView> handler = new DataContextChangedHandler<UserControlView>(); public UserControlView() { this.InitializeComponent(); this.handler.Bind(this); } public void DataContextChanged(UserControlView sender, DependencyPropertyChangedEventArgs e) { var viewModel = e.NewValue as UserControlViewModel; if (viewModel == null) { return; } viewModel.SomeEventRaised += (o, args) => VisualStateManager.GoToState(this, "TheOtherState", false); } } }

Espero que ayude.