I'm wondering what the best method is for triggering external functions (or commands) from within a inner list item.
For example, I have a FooManager
object which contains an ObservableCollection of Foo
objects called MyFoos
. FooManager also has a function called ProcessFoo(Foo foo)
.
<StackPanel DataContext="FooManager">
<ListView ItemsSource="{Binding MyFoos}" >
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Button Content="Do Something"
Command="{Binding Path=SomeFooCommand} />
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
How do I trigger the ProcessFoo(Foo foo) function (and passing the 'clicked' Foo) by clicking the "Do Something" button?
I realise I could use code-behind to do this, but I'm wondering what the cleanest MVVM approach is. Should the ViewModel for Foo contain a reference to it's FooManager, or is it bad practice for ViewModels to reference each other?
Thanks to @Clemens. In the FooManager class, add a command which takes a Foo VM as a parameter. The Button in the DataTemplate can then trigger this by using a RelativeSource
in the binding, and passing itself (an empty {Binding}
) as parameter.
<StackPanel DataContext="FooManager">
<ListView ItemsSource="{Binding MyFoos}" >
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Button Content="Do Something"
Command="{Binding Path=DataContext.ProcessFoo, RelativeSource={RelativeSource AncenstorType=ListView}}
CommandParameter={Binding} />
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>