在WinRT XAML UserControl中访问DataContext的位置



我有UserControlViewModel引发一个事件:

public event EventHandler<EventArgs> StuffDone;

MainPageViewModel内部创建并初始化UserControlViewModel的对象:

this.userControlViewModel = new UserControlViewModel();

MainPageViewModelMainPage的视图模型。

主页。在xaml中,我有以下代码将UserControlView UserControl放在MainPage中并初始化其DataContext:

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

到目前为止一切正常。

现在我想订阅UserControlView内的StuffDone事件。我想到的第一件事是在UserControlViewLoaded事件处理程序中做到这一点;然而,此时的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);
        }
    }
}

希望对你有帮助。

最新更新