答えは: MVVM. コード ビハインドでイベント登録を使用しないで、ViewModel でコマンドを呼び出すようにします。まず、Data オブジェクトにバインドする代わりに、ViewModel (または、リスト内にいる場合は単一のリスト項目を表す ViewModel) にバインドします。次に、Click イベントを使用する代わりに、データバインドされた VM で直接呼び出すことができる Command を ViewModel に公開させます。
私の国連ニュースOSS WP7 アプリの簡単な例を次に示します: ( XAML、C# )
<DataTemplate x:Key="ArticleItemDataTemplate">
<StackPanel>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Command="{Binding NavigateToArticle}" Header="read article"/>
<toolkit:MenuItem Command="{Binding ShareViaEmail}" Header="share via email"/>
<toolkit:MenuItem Command="{Binding ShareOnFacebook}" Header="share on facebook"/>
<toolkit:MenuItem Command="{Binding ShareOnTwitter}" Header="share on twitter"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<TextBlockText="{Binding Title}">
</StackPanel>
</DataTemplate>
public ICommand ShareOnTwitter
{
get
{
return new RelayCommand(() =>
IoC.Get<ISocialShareService>().ShareOnTwitter(ShareableOnSocialNetwroks));
}
}
public ICommand ShareOnFacebook
{
get
{
return new RelayCommand(() =>
IoC.Get<ISocialShareService>().ShareOnFacebook(ShareableOnSocialNetwroks));
}
}
public ICommand ShareViaEmail
{
get
{
return new RelayCommand(() =>
IoC.Get<ISocialShareService>().ShareViaEmail(ShareableOnSocialNetwroks));
}
}
そして、これは私のNeurons WP7 OSS プロジェクトで使用された同じアイデアの別の単純化されたサンプルです: ( XAML、C# )
<DataTemplate x:Key="YouTubeVideoItem">
<Grid>
<Button >
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="False">
<toolkit:MenuItem Command="{Binding NavigateToVideo}" Header="play video" />
<toolkit:MenuItem Command="{Binding ViewInBrowser}" Header="open in browser" />
<toolkit:MenuItem Command="{Binding SendInEmail}" Header="share via email" />
<toolkit:MenuItem Command="{Binding FacebookInBrowser}" Header="share on facebook" />
<toolkit:MenuItem Command="{Binding TweetInBrowser}" Header="share on twitter" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="Click">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding NavigateToVideo}"/>
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
<StackPanel Orientation="Horizontal">
<Image Height="90" Source="{Binding ImageUrl}" />
<TextBlock Width="271" Text="{Binding Title}" />
</StackPanel>
</Button>
</Grid>
</DataTemplate>
public ICommand ViewInBrowser
{
get
{
return new RelayCommand(() =>
TaskInvoker.OpenWebBrowser(this.ExternalLink.OriginalString)
);
}
}
public ICommand TweetInBrowser
{
get
{
return new RelayCommand(() =>
IoC.Get<IMessenger>().Send(new NavigateToMessage(PageSources.WebBrowser, TwitterUri)));
}
}
public ICommand FacebookInBrowser
{
get
{
return new RelayCommand(() =>
IoC.Get<IMessenger>().Send(new NavigateToMessage(PageSources.WebBrowser, FacebookUri)));
}
}