2013-03-08 7 views
5

ich UserControlViewModel habe, die ein Ereignis auslöst:Wo Zugriff auf Datacontext in WinRT XAML Usercontrol

public event EventHandler<EventArgs> StuffDone; 

die Aufgabe UserControlViewModel erstellt und initialisiert innen MainPageViewModel:

this.userControlViewModel = new UserControlViewModel(); 

MainPageViewModel ist die Ansicht -Modell für MainPage.

In MainPage.xaml, habe ich den folgenden Code bekam UserControlViewUserControl in MainPage zu platzieren und initialisieren seine DataContext:

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

Bisher funktioniert alles einwandfrei.

Jetzt möchte ich StuffDone Ereignis innerhalb UserControlView unterzeichnen. Das erste, was mir einfällt, ist, es innerhalb Loaded Event-Handler von UserControlView; jedoch ist die DataContext an diesem Punkt immer noch null. Scanning den Rest von UserControl Ereignisse gab mir keine Ahnung.

Also, wo ist der richtige Ort, um die DataContext zu bekommen und seine Veranstaltungen zu abonnieren?

Vielen Dank im Voraus.

+2

Schmerzhaft. Es gibt kein Ereignis und keine überschreibenden Metadaten für die DataContext-Abhängigkeitseigenschaft. Geh nach Hause, Microsoft, du bist betrunken. Dieser Typ hat hier eine Lösung: http://doteteers.net/blogs/vbandi/archive/2013/01/23/datacontextchanged-event-for-winrt.aspx Hacky. – Will

+0

Ich habe das schon mal gemacht und es funktioniert gut für mich. Aber ich habe "Mode = TwoWay" benutzt. Im Loaded-Ereignis von UserControl kann ich auf ViewModel zugreifen (natürlich müssen Sie DataCotext auf Ihr ViewModel übertragen, um darauf zuzugreifen) – SachiraChin

+0

@Sach, was genau gemacht? was [Will] (http://stackoverflow.com/users/1228/will) vorgeschlagen? Wenn es etwas anderes ist, können Sie bitte ein Beispiel dafür geben, was Sie getan haben? – TheBlueSky

Antwort

1

UPDATE: Ereignis wird in WinRT für Windows 8.1 unterstützt. Verwenden Sie Folgendes nur, wenn Sie WinRT für Windows 8 oder eine andere Plattform codieren, die DataContextChanged nicht unterstützt.

Scheint so, als ob es keine direkte Möglichkeit gibt, es zu tun, und die von Will auf seinem Kommentar vorgeschlagene Abhilfe ist der einfachste Weg zu gehen.

Unten ist meine Version der Abhilfe, die für mich funktioniert:

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); 
     } 
    } 
} 

Hoffe, dass hilft.

+0

Ich bevorzuge diesen Ansatz: http://amrred.wordpress.com/2013/01/24/winrt-datacontext-changed-event-and-trigger/ – HappyNomad

Verwandte Themen