2011-03-23 84 views
2

我有一個填充了一些視圖模型類的觀察集合一個ItemsControl,就像這樣:獲取項目在ItemsControl中

<ItemsControl ItemsSource="{Binding MyCollection}"> 
    <ItemsControl.ItemTemplate> 
    <DataTemplate Type="{x:Type local:MyViewModel}"> 
     <Button Content="{Binding ActionName}" Click="ClickHandler"/> 
    </DataTemplate> 
    <ItemsControl.ItemTemplate> 
</ItemsControl> 

偉大的作品,看起來不錯,但我似乎無法弄清楚如何讓「ClickHandler」知道由數據模板表示的類「MyViewModel」。看哪!

private void ClickHandler(object sender, RoutedEventArgs e) 
{ 
    // The 'sender' is the button that raised the event. Great! 
    // Now how do I figure out the class (MyViewModel) instance that goes with this button? 
} 

回答

4

你自己的答案會在這個特定的情況下做到這一點。這裏還有一個技術,它,而要複雜得多,也可以在任何情況下工作的複雜性,無論:

sender開始(這是一個Button),使用VisualTreeHelper.GetParent直到找到一個ContentPresenter。這是您指定的ItemTemplate針對每個項目託管的UIElement的類型。我們將ContentPresenter放入變量cp。 (重要提示:如果您的ItemsControlListBox,則代替ContentPresenter我們會尋找ListBoxItem)。請撥ItemsControl.ItemContainerGenerator.ItemFromContainer(cp)。要做到這一點,你需要參考具體的ItemsControl,但這不應該很難 - 例如,你可以給它一個Name並使用你自己的View自己的FrameworkElement.FindNameItemFromContainer方法將返回您的ViewModel。

所有這一切,我從Dr.WPF的愚蠢有用和令人大開眼界的帖子中學到了。

+0

啊挺好的。這顯然會比我列出的方法更好,但只適用於非默認數據上下文非常複雜的模板。 – 2011-03-23 03:20:49

+0

@ A.R.:確切地說。 – Jon 2011-03-23 03:22:39

+0

這可能很愚蠢,但你能結合我的答案和你的?他們在某種意義上都是「正確的」,我想給你一個綠色檢查,因爲你的檢查更加完整。我認爲其他人可以從兩種方法中受益,取決於他們在做什麼。 – 2011-03-23 12:26:11

6

OK咄,我幾乎立刻意識到,這是在「發件人」的「DataContext的」。除非社區認爲這個問題太明顯,否則我會留下來的。

private void ClickHandler(object sender, RoutedEventArgs e) 
{ 
    // This is the item that you want. Many assumptions about the types are made, but that is OK. 
    MyViewModel model = ((sender as FrameworkElement).DataContext as MyViewModel); 
} 
+0

這比被接受的答案更好,更容易,也適用於其他類似的情況。 – 2013-06-04 12:21:33