I'm rebuilding Josh Smith's WPF CommandSink example and there are a few things that I don't understand about his databinding, especially about how datacontext is inherited when a view is contained in another view which is contained in a window which has a datacontext.
- all databinding is declared in the XAML files, there is absolutely no code behind the Window or either of the Views (nice)
- the top Window defines its DataContext as CommunityViewModel and simply displays the CommunityView
Question: so now in the CommunityViewModel, what does the
jas:CommandSinkBinding.CommandSink="{Binding}"
do actually? "CommandSink" is an attached property so is this "attaching" the inherited Binding that comes from DemoWindow as the value of the attached property called "CommandSink" on the CommandSinkBinding object?Question: also, PersonView doesn't seem to have a DataContext yet it has lines such as
<TextBlock Text="{Binding Name}" Width="60" />
which assume that a binding is set. So does PersonView automatically get its binding from the line in CommunityViewItemsSource="{Binding People}"
?
Thanks for any clarification here.
DemoWindow.xaml:
<Window
x:Class="VMCommanding.DemoWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:VMCommanding.View"
xmlns:vm="clr-namespace:VMCommanding.ViewModel"
FontSize="13"
ResizeMode="NoResize"
SizeToContent="WidthAndHeight"
Title="ViewModel Commanding Demo"
WindowStartupLocation="CenterScreen"
>
<Window.DataContext>
<vm:CommunityViewModel />
</Window.DataContext>
<Window.Content>
<view:CommunityView />
</Window.Content>
</Window>
CommunityView.xaml:
<UserControl
x:Class="VMCommanding.View.CommunityView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:jas="clr-namespace:VMCommanding"
xmlns:view="clr-namespace:VMCommanding.View"
xmlns:vm="clr-namespace:VMCommanding.ViewModel"
jas:CommandSinkBinding.CommandSink="{Binding}"
>
<UserControl.CommandBindings>
<jas:CommandSinkBinding Command="vm:CommunityViewModel.KillAllMembersCommand" />
</UserControl.CommandBindings>
<DockPanel Margin="4">
<ItemsControl
DockPanel.Dock="Bottom" ItemsSource="{Binding People}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<view:PersonView />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button
Command="vm:CommunityViewModel.KillAllMembersCommand"
Content="Kill All"
Margin="0,0,0,8"
/>
</DockPanel>
</UserControl>
PersonView.xml:
<UserControl
x:Class="VMCommanding.View.PersonView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:jas="clr-namespace:VMCommanding"
xmlns:vm="clr-namespace:VMCommanding.ViewModel"
jas:CommandSinkBinding.CommandSink="{Binding}"
>
<UserControl.CommandBindings>
<jas:CommandSinkBinding Command="vm:PersonViewModel.DieCommand" />
<jas:CommandSinkBinding Command="vm:PersonViewModel.SpeakCommand" />
</UserControl.CommandBindings>
<UserControl.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="0,0,6,0" />
<Style.Triggers>
<DataTrigger Binding="{Binding CanDie}" Value="False">
<Setter Property="Foreground" Value="#88000000" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<StackPanel Margin="2" Orientation="Horizontal">
<TextBlock Text="Name:" FontWeight="Bold" />
<TextBlock Text="{Binding Name}" Width="60" />
<TextBlock Text="Age:" FontWeight="Bold" />
<TextBlock Text="{Binding Age}" Width="40" />
<Button
Command="vm:PersonViewModel.SpeakCommand"
CommandParameter="Howdy partner!"
Content="Speak"
Margin="0,0,6,0"
Width="60"
/>
<Button
Command="vm:PersonViewModel.DieCommand"
Content="Die"
Width="60"
/>
</StackPanel>
</UserControl>