从 ItemsControl 中的模板获取项目
我有一个 ItemsControl,其中填充了一些 ViewModel 类的可观察集合,如下所示:
<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?
}
I have an ItemsControl that is populated with an observable collection of some ViewModel classes, like so:
<ItemsControl ItemsSource="{Binding MyCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate Type="{x:Type local:MyViewModel}">
<Button Content="{Binding ActionName}" Click="ClickHandler"/>
</DataTemplate>
<ItemsControl.ItemTemplate>
</ItemsControl>
Works great, looks great, but I can't seem to figure out how to get the "ClickHandler" to be aware of the class 'MyViewModel' that is represented by the data template. Behold!
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?
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,我几乎立即意识到这是“发送者”的“DataContext”。我将保留这个问题,除非社区认为这个问题太明显了。
OK duh, I almost immediately realized that it is the 'DataContext' of the 'sender'. I am going to leave this up unless the community thinks that this question is just too obvious.
在这种特定情况下,您自己的答案将发挥作用。这是另一种技术,虽然要复杂得多,但无论复杂程度如何,都适用于任何场景:
从
sender
(这是一个Button
)开始,使用VisualTreeHelper.GetParent
直到您找到一个ContentPresenter
。这是您为每个项目指定的ItemTemplate
托管的UIElement
类型。我们将ContentPresenter
放入变量cp
中。 (重要提示:如果您的ItemsControl
是ListBox
,那么我们将寻找ListBoxItem
而不是ContentPresenter
代码>等)。然后,调用
ItemsControl.ItemContainerGenerator.ItemFromContainer (cp)
。为此,您需要对特定的ItemsControl
有一些引用,但这应该不难 - 例如,您可以给它一个Name
并使用FrameworkElement.FindName
从你的视图本身。ItemFromContainer
方法将返回您的 ViewModel。所有这些都是我从 博士 WPF 。
Your own answer will do the trick in this specific case. Here's another technique which, while much more complicated, will also work on any scenario regardless of complexity:
Starting from
sender
(which is aButton
), useVisualTreeHelper.GetParent
until you find aContentPresenter
. This is the type ofUIElement
that theItemTemplate
you specified is hosted into for each of your items. Let's put thatContentPresenter
into the variablecp
. (Important: if yourItemsControl
were aListBox
, then instead ofContentPresenter
we 'd look for aListBoxItem
, etc).Then, call
ItemsControl.ItemContainerGenerator.ItemFromContainer(cp)
. To do that, you will need to have some reference to the specificItemsControl
but this shouldn't be hard -- you can, for example, give it aName
and useFrameworkElement.FindName
from your View itself. TheItemFromContainer
method will return your ViewModel.All of this I learned from the stupidly useful and eye-opening posts of Dr. WPF.