We have a screen and its view model:
public class ScreenViewModel : BaseViewModel
{
[NotifyPropertyChanged]
public List<Node> Nodes { get; set; }
public ICommand NodeClickedCommand { get; set; }
public ScreenViewModel()
{
NodeClickedCommand = new RelayCommand(NodeClicked);
// ....
// Some code that binds Nodes.
// ....
}
private void NodeClicked()
{
MessageBox.Show("This is never shown");
}
}
On this page we have custom control (CustomControl) and following xaml to bind the command:
<UserControl x:Class="ScreenView"
x:Name="Screen"
>
<CustomControl Nodes="{Binding Nodes}">
<CustomControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding ElementName=Screen,
Path=DataContext.NodeClickedCommand}">
<TextBlock>hello</TextBlock>
</Button>
</DataTemplate>
</CustomControl.ItemTemplate>
</CustomControl>
Our custom SL control uses the above template (DataTemplate) to display it's children:
foreach(Node node in Nodes)
{
FrameworkElement frameworkElement = (FrameworkElement)ItemTemplate.LoadContent();
frameworkElement.DataContext = node ;
this._canvas.Children.Add(frameworkElement);
}
We are sure that:
- ViewModel is correctly bound to View
- All nodes are displayed correctly
- Regular binding works correctly
- There are no binding warnings in VS
- Command binding works if we bind with Command="{Binding NodeClickedCommand}", but of course this binds to command that should exist on single node and we want to bind to command that exists on the screen view model.
- Simmilar scenario works with ListBox and ListBox.ItemTemplate
The problem is that NodeClickedCommand is never bound, why?