2013-03-08 8 views
5

mam UserControlViewModel który wywołuje zdarzenie:Gdzie dostęp DataContext w WinRT XAML UserControl

public event EventHandler<EventArgs> StuffDone; 

Przedmiotem UserControlViewModel jest tworzony i inicjowany wewnątrz MainPageViewModel:

this.userControlViewModel = new UserControlViewModel(); 

MainPageViewModel jest widok -Model dla MainPage.

W MainPage.xaml, mam następujący kod do umieszczenia UserControlViewUserControl w MainPage i zainicjować jego DataContext:

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

tej pory wszystko działa bez zarzutu.

Teraz chciałbym subskrybować wydarzenie StuffDone wewnątrz UserControlView. Pierwszą rzeczą, która przyszła mi do głowy to zrobienie tego wewnątrz Loaded event-handler z UserControlView; jednak w tym momencie DataContext jest nadal null. Skanowanie reszty zdarzeń nie dało mi żadnej wskazówki.

Więc, gdzie jest właściwe miejsce, aby uzyskać DataContext i zapisać się na jego wydarzenia?

Z góry dziękuję.

+2

Bolesne. Brak zdarzenia i żadnych nadpisujących metadanych w właściwości zależności DataContext. Idź do domu, Microsoft, jesteś pijany. Ten facet ma rozwiązanie tutaj: http://dotneteers.net/blogs/vbandi/archive/2013/01/23/datacontextchanged-event-for-winrt.aspx Hacky. – Will

+0

Zrobiłem to wcześniej i to działa dobrze dla mnie. Ale użyłem "Mode = TwoWay". W załadowanym zdarzeniu UserControl, mogę uzyskać dostęp do ViewModel (oczywiście musisz rzucić DataCotext do swojego ViewModel, aby uzyskać do niego dostęp) – SachiraChin

+0

@ Co, co zrobiłeś? co zasugerował [Will] (http://stackoverflow.com/users/1228/will)? Jeśli jest coś innego, czy możesz podać przykład tego, co zrobiłeś? – TheBlueSky

Odpowiedz

1

UPDATE: DataContextChanged Zdarzenie jest obsługiwane w WinRT dla Windows 8.1. Poniższe informacje należy stosować tylko w przypadku kodowania przeciwko WinRT dla systemu Windows 8 lub innej platformy, która nie obsługuje DataContextChanged.

Wygląda na to, że nie ma prostego sposobu, aby to zrobić, a obejście sugerowane przez Will na jego komentarzu jest najprostszym sposobem.

Poniżej jest moja wersja obejście, które działa na mnie:

W IDataContextChangedHandler.Generic.cs:

using Windows.UI.Xaml; 

namespace SomeNamespace 
{ 
    public interface IDataContextChangedHandler<in T> where T : FrameworkElement 
    { 
     void DataContextChanged(T sender, DependencyPropertyChangedEventArgs e); 
    } 
} 

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

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

Nadzieję, że pomaga.

+0

Preferuję takie podejście: http://amrreda.wordpress.com/2013/01/24/winrt-datacontext-changed-event-and-trigger/ – HappyNomad

Powiązane problemy