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>
If you set the
ItemsSourceof an ItemsControl, the DataContexts of the items in that control are directly mapped to the items of theItemsSource.