I've got UserControlViewModel
which raises an event:
public event EventHandler<EventArgs> StuffDone;
An object of UserControlViewModel
is created and initialised inside MainPageViewModel
:
this.userControlViewModel = new UserControlViewModel();
MainPageViewModel
is the View-Model for MainPage
.
In MainPage.xaml, I've got the following code to place UserControlView
UserControl
in MainPage
and initialise its DataContext
:
<views:UserControlView DataContext="{Binding userControlViewModel, Mode=OneWay}" IsHitTestVisible="False"></views:UserControlView>
So far everything works fine.
Now I'd like to subscribe to StuffDone
event inside UserControlView
. The first thing occurred to me is to do it inside Loaded
event-handler of UserControlView
; however, the DataContext
at that point is still null
. Scanning the rest of UserControl
events gave me no clue at all.
So, where is the right place to get the DataContext
and subscribe to its events?
Thanks in advance.
UPDATE: DataContextChanged event is supported in WinRT for Windows 8.1. Use the following only if you're coding against WinRT for Windows 8, or whatever platform that does not support DataContextChanged
.
Seems like there is no straightforward way to do it and the workaround suggested by Will on his comment is the simplest way to go.
Below is my version of the workaround which works for me:
In IDataContextChangedHandler.Generic.cs:
using Windows.UI.Xaml;
namespace SomeNamespace
{
public interface IDataContextChangedHandler<in T> where T : FrameworkElement
{
void DataContextChanged(T sender, DependencyPropertyChangedEventArgs e);
}
}
In 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());
}
}
}
In 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);
}
}
}
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With