我有UserControlViewModel
引发一个事件:
public event EventHandler<EventArgs> StuffDone;
在MainPageViewModel
内部创建并初始化UserControlViewModel
的对象:
this.userControlViewModel = new UserControlViewModel();
MainPageViewModel
是MainPage
的视图模型。
主页。在xaml中,我有以下代码将UserControlView
UserControl
放在MainPage
中并初始化其DataContext
:
<views:UserControlView DataContext="{Binding userControlViewModel, Mode=OneWay}" IsHitTestVisible="False"></views:UserControlView>
到目前为止一切正常。
现在我想订阅UserControlView
内的StuffDone
事件。我想到的第一件事是在UserControlView
的Loaded
事件处理程序中做到这一点;然而,此时的DataContext
仍然是null
。扫描UserControl
事件的其余部分给了我一点线索。
那么,哪里是获得DataContext
并订阅其事件的正确位置呢?
UPDATE: WinRT for Windows 8.1支持DataContextChanged事件。只有在Windows 8上使用WinRT或任何不支持DataContextChanged
的平台上编写代码时,才能使用以下代码。
似乎没有直接的方法可以做到这一点,而Will在他的评论中建议的变通方法是最简单的方法。
下面是我的版本,它适用于我:
在IDataContextChangedHandler.Generic.cs:using Windows.UI.Xaml;
namespace SomeNamespace
{
public interface IDataContextChangedHandler<in T> where T : FrameworkElement
{
void DataContextChanged(T sender, DependencyPropertyChangedEventArgs e);
}
}
在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());
}
}
}
在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);
}
}
}
希望对你有帮助。