5

我有UserControlViewModel一个引发事件的事件:

public event EventHandler<EventArgs> StuffDone;

UserControlViewModel在内部创建并初始化一个对象MainPageViewModel

this.userControlViewModel = new UserControlViewModel();

MainPageViewModel是 的视图模型MainPage

在 MainPage.xaml 中,我有以下代码可以放入UserControlView UserControlMainPage初始化它DataContext

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

到目前为止一切正常。

现在我想订阅StuffDone里面的事件UserControlView。我想到的第一件事是在Loaded事件处理程序中进行UserControlView;但是,DataContext此时仍然是null. 扫描其余的UserControl事件根本没有给我任何线索。

那么,获取DataContext和订阅其事件的正确位置在哪里?

提前致谢。

4

1 回答 1

1

更新:Windows 8.1 的 WinRT 支持DataContextChanged事件。仅当您针对 WinRT for Windows 8 或任何不支持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);
        }
    }
}

希望有帮助。

于 2013-03-15T08:47:15.187 回答