问题
First off, I'm still getting used to Caliburn and WPF, so I may be doing this the wrong way. I'd love to know a better way!
I have a Conductor
shell view model, which has a view with some shared elements, and a content control for the ActiveItem
. Now, I want a set of buttons from the ActiveItem
view model to be displayed outside the content control, but still have their click events go to the active view model. I've tried adding an ItemsControl
like this:
<ItemsControl x:Name="ActiveItem_Buttons">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" HorizontalAlignment="Right"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}" Margin="10" Height="25" Width="80">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="{Binding Name}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
(I'm doing the Interaction.Trigger
part since I cannot bind to x:Name
which would cause Caliburn to wire it automagically)
However, I get an exception stating that Caliburn cannot find a matching method. It seems like it starts bubbling the event from the shell view model, instead of the active item view model. How can I set the "starting point" of the event bubbling? I found and tried the attached property cal:View.Model="{Binding ActiveItem}"
, but that did not seem to help.
EDIT: For clarity: the Buttons
property is defined on the view model base class ButtonScreenBase
, and the shell inherits Conductor<ButtonScreenBase>
回答1:
Rather don't use events and event handling in WPF, especially in conjunction with MVVM. Use the Command
pattern instead. For user actions this means you can trigger Commands via gestures, clicks and other kind of user interaction events in the View and contain the business logic in the Command
class/methods which is triggered in the ViewModel from the View, thus maintaining the separation of user interface logic and business logic.
I recommend this link for learning about Commands and how you can implement them (and MVVM from base principles) : http://kentb.blogspot.co.uk/2009/04/mvvm-infrastructure-delegatecommand.html
回答2:
update: went back to check some other posts about this particular problem, an explanation about the problem from the man himself.
Bind a Command to a Button inside a ListView with Caliburn.Micro
<Button Content="{Binding Name}" cal:Bind="{Binding}" Margin="10" Height="25" Width="80">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="{Binding Name}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
same thing it's an inherit issue with datatemplating.
来源:https://stackoverflow.com/questions/24825722/bubbling-events-from-bound-viewmodel-goes-to-parent