我正在重建Josh Smith's WPF CommandSink example并且有一些我不了解他的数据绑定的事情,特别是当一个视图包含在另一个包含在窗口中的视图中时,如何继承datacontext一个datacontext。
问题:所以现在在CommunityViewModel中,jas:CommandSinkBinding.CommandSink="{Binding}"
实际上做了什么? “CommandSink”是一个附加属性,所以这是“附加”来自DemoWindow的继承Binding,作为CommandSinkBinding对象上名为“CommandSink”的附加属性的值吗?
问题:另外,PersonView似乎没有DataContext但它有<TextBlock Text="{Binding Name}" Width="60" />
这样的行,它们假设已设置绑定。 PersonView也会自动从CommunityView ItemsSource="{Binding People}"
中的行中获取其绑定?
感谢您的任何澄清。
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>
答案 0 :(得分:4)
如果设置ItemsControl的ItemsSource
,则该控件中项目的DataContexts将直接映射到ItemsSource
的项目。
答案 1 :(得分:3)
控件继承它的父DataContext,除非为控件明确指定了一个。所以第二个问题的答案是肯定的。
答案 2 :(得分:1)
PersonView由社区视图中的ItemsControl的DataTemplate生成(CommunityView.xaml:16)。
DataTemplates自动将其视觉效果的DataContext分配给模板显示的数据。这就是WPF的工作方式。
CommunityView通过Window的继承来获取其DataContext集。
附加的命令接收器属性在具有附加属性赋值的对象的CommandBindings属性中包含的所有CommandSinkBinding对象上设置实例CommandSink属性。因此,在CommunityView.xaml中,CommunityView(KillAll)中所有CommandSinkBindings的CommandSink都通过绑定设置为视图的DataContext。
CommandSink属性用于调用正确目标上的Execute和CanExecute函数(在本例中为ViewModel)。
答案 3 :(得分:0)
DataContext是FrameworkElement(所有WPF控件的基类)上的属性,并作为DependencyProperty实现。这意味着逻辑树中的所有后代元素共享相同的DataContext。