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.