美好的一天,
我在这里变得绝望了.考虑以下用例.
I'm getting desperate here. Consider the following use case.
我有一个列表框,其中的项是自定义模板控件.它有几个按钮,此自定义控件为其后的代码提供了事件处理程序.无论何时单击按钮,我都会通过DataContext调用自定义控件绑定到的对象的方法.因此,当用户单击停止时,我调用_context.stopDownload(),其余的由对象完成.
I have a listbox which item's are custom templated control. It has several buttons for which this custom control has event handlers in code behind. Whenever button is clicked I call a method of the object my custom control is bound to through the DataContext. So, when user clicks stop, I call _context.stopDownload() and object does the rest.
但是,我有一个按钮可以开始播放内容.我试图以某种方式在核心级别上监听此按钮的click事件,而不是在代表列表框项目UI的自定义控件后面的代码中.
But, I have one button which should start the playback of the content. I am trying to somehow listen to this button's click event on the core level, not in the code behind of my custom control which represents listbox's item UI.
因此,总结一下:
我不知道#3.除其他外,在设置ItemsSource来连接事件处理程序之后,我尝试过类似的操作,但是container始终为null.
I can't figure out #3. Among other things, I've tried doing something like that after I set the ItemsSource to wire the event handler, but container is always null.
DownloadsListElement.ItemsSource = _downloadsList; foreach (var item in DownloadsListElement.ItemsSource) { var container = DownloadsListElement.ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement; }我还尝试了在列表框上按网格按钮,并尝试使用Grid的MouseLeftButtonDown/Up上的VisualTreeHelper单击按钮,但是当我单击按钮时,这些按钮从未被调用.
I have also tried button a grid over the listbox and trying to get button clicked using VisualTreeHelper on Grid's MouseLeftButtonDown/Up, but those are never invoked when I click on the button.
我认为,当我在某个全局对象中注册事件处理程序,然后从DataTemplate内部的自定义控件调用事件处理程序时,唯一可行的解决方案是使用某种命令模式.
I'm thinking that only possible solution would be using some kind of commands pattern when I register event handler in some global object and then call it from the custom control inside the DataTemplate.
我没主意,希望有人对此问题有所了解.
I'm out of the ideas and hope someone had something similar to this issue.
谢谢.
更新
多亏了McGamagle和ChrisW,我才开始工作.我在按钮上拥有的最终代码如下:
Thanks to McGamagle and ChrisW I got it working. The final code I have on the button looks like this:
<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <ei:CallMethodAction TargetObject="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType=local:ListBoxExt}}" MethodName="PlayButton_Click"/> </i:EventTrigger> </i:Interaction.Triggers>谢谢你们!
推荐答案我的理解是,您想将处理程序附加到ListBox项的DataTemplate内的项上,该处理程序属于父级的DataContext.
My understanding is that you want to attach a handler to an item inside a ListBox item's DataTemplate, where the handler belongs to the parent's DataContext.
您可以使用RelativeSource FindAncestor绑定进行此操作.您可能要考虑使用ICommand代替处理程序,但是如果确实需要处理程序,则可以使用Blend SDK的 CallMethodAction .
You can do this using a RelativeSource FindAncestor binding. You might want to consider using an ICommand instead of a handler, but if you do need a handler, then you can use the Blend SDK's CallMethodAction.
XAML应该看起来像这样(其中"SomeCommand"是ListBox数据上下文的ICommand属性):
The XAML should look something like this (where "SomeCommand" is an ICommand property of the ListBox's data context):
<ListBox> <ListBox.ItemTemplate> <DataTemplate> <Button Command="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=DataContext.SomeCommand}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox>或使用"CallMethodAction"技术(此处"HandleButtonClick"必须是ListBox数据上下文的公共方法):
Or using the "CallMethodAction" technique (here "HandleButtonClick" must be a public method of the ListBox's data context):
<ListBox> <ListBox.ItemTemplate> <DataTemplate> <Button> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <ei:CallMethodAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=DataContext.SomeCommand}" MethodName="HandleButtonClick" /> </i:EventTrigger EventName="Click"> </i:Interaction.Triggers> </Button> </DataTemplate> </ListBox.ItemTemplate> </ListBox>更多推荐
Silverlight,DataTemplate,绑定到单击事件
发布评论