3

这是关于Josh Smith 关于 MVVM和示例应用程序的 MSDN 文章。我知道关于这个主题有很多关于 SO 的问题,我已经全部探索过了。他们中的大多数都专注于 MVVM,但我认为我的问题是,与 MVVM 相比,与 XAML 相关的更多。

示例应用程序包含工作区区域的以下 XAML -

<Border Grid.Column="2" Style="{StaticResource MainBorderStyle}">
    <ContentControl Content="{Binding Path=Workspaces}" ContentTemplate="{StaticResource ResourceKey=WorkspacesTemplate}"/>
</Border>

相关资源是 -

//Explains how to render the 'Workspace' content area in the main window
<DataTemplate x:Key="WorkspacesTemplate">
    <TabControl Margin="4" ItemsSource="{Binding}"
                IsSynchronizedWithCurrentItem="True"                    
                ItemTemplate="{StaticResource ResourceKey=ClosableTabItemTemplate}"/>
</DataTemplate>

//Explains how to render a tab item with a close button
<DataTemplate x:Key="ClosableTabItemTemplate">
    <DockPanel Width="120">
        <Button Command="{Binding Path=CloseCommand}" Content="X" Cursor="Hand" 
                DockPanel.Dock="Right" Focusable="False" FontFamily="Courier" 
                FontSize="9" FontWeight="Bold" Margin="0,1,0,0" Padding="0" 
                VerticalContentAlignment="Bottom" Width="16" Height="16"/>
        <ContentPresenter Content="{Binding Path=DisplayName}" VerticalAlignment="Center"/>
    </DockPanel>
</DataTemplate>

我还是不明白的——

  • 语法ItemsSource="{Binding}"应该将 ItemsSource 直接绑定到 TabControl 的 DataContext,而不是绑定到 DataContext 的任何属性。但是 TabControl 的 DataContext 到底是在哪里设置的呢?
  • 如何Content="{Binding Path=Workspaces}"在 TabControl 的 ItemsSource 和 Workspaces(WorkspaceViewModel 的 ObservableCollection)之间创建绑定?
  • 文章说通过依赖数据绑定,a的Content属性TabItem接收一个ViewModelBase派生的对象来显示。如何 ?!?好的,通过数据绑定。但这对我来说太抽象了。

一般来说,我缺少the way binding is flowing/working through these two resources behind the scene在 TabItems 中加载视图。对我来说,就像是什么导致什么被绑定到什么

这篇传奇文章和示例应用程序对于 WPF/MVVM 初学者来说非常有用。但这不是很详细。我自己已经学会了使用 MVVM 和这个。我认为还有一些我一样的人。那么,任何人都可以更详细地解释绑定序列吗?

相关说明:

也许它会给你一些我在这方面已经知道的信息,并帮助你回答。我是初级 WPF 应用程序开发人员。由于我对 XAML 不太了解 -

  • 我通过DataTemplate在 ViewModel 类型发生时显​​示 View 的类型来了解魔术,然后将 ViewModel 设置为该 View 的 DataContext
  • 我的理解是,Content 告诉在 ContentControl 上显示什么,而 ContentTemplate 告诉如何显示该内容。
  • 我有比基本数据绑定概念更多的东西,并且我曾在一些 WPF/MVVM 项目中工作过。
4

2 回答 2

3

语法 ItemsSource="{Binding}" 应该将 ItemsSource 直接绑定到 TabControl 的 DataContext,而不是绑定到 DataContext 的任何属性。但是 TabControl 的 DataContext 到底是在哪里设置的呢?

由于是数据模板,它将(通过 WPF)TabControl将其设置为它正在模板化的数据项。DataContext实际上,数据模板中的根级项DataContext将由 WPF 设置。在这种情况下,它是一个TabControl.

由于数据模板已分配给ContentControl'ContentTemplate属性,它将自动接收ContentControl'Content作为其DataContext.

Content="{Binding Path=Workspaces}" 究竟是如何在 TabControl 的 ItemsSource 和 Workspaces(WorkspaceViewModel 的 ObservableCollection)之间创建绑定的?

我认为我之前的回答解决了这个问题,但让我以直接回答这个问题的形式重新陈述它。上的绑定ContentControl确保将DataContextforDataTemplate设置为工作区集合。因此,TabControl可以通过指定Binding不带 a 的 a来绑定到工作区集合Path

文章说通过依赖数据绑定,TabItem 的 Content 属性接收 ViewModelBase 派生的对象进行显示。如何 ?!?好的,通过数据绑定。但这对我来说太抽象了。

同样,这归结为 WPF 自动分配正确的对象作为生成项的数据上下文(TabItem在本例中为 a)。当一个ItemsControl(例如TabControl)绑定到一个集合时,它会为绑定集合中的每个项目生成一个容器(TabItem在本例中为 a)。容器自动接收数据项(在本例中为工作区视图模型)作为其数据上下文。

于 2012-09-12T12:55:13.357 回答
0

“但是 TabControl 的 DataContext 到底是在哪里设置的呢?” Workspaces 是 DataContext,因此是 TabControl 的 Itemssource。

<ContentControl Content="{Binding Path=Workspaces}" ContentTemplate="{StaticResource ResourceKey=WorkspacesTemplate}"/>

“Content="{Binding Path=Workspaces}" 究竟是如何在 TabControl 的 ItemsSource 和 Workspaces(WorkspaceViewModel 的 ObservableCollection)之间创建绑定的?” 工作区是 DataTemplate/TabControl 的 DataContext,ItemsSource 设置为 DataContext。

 <TabControl Margin="4" ItemsSource="{Binding}"

“文章说通过依赖数据绑定,TabItem 的 Content 属性接收 ViewModelBase 派生的对象来显示。如何?!?” 我不知道这篇文章,但我假设 Workspaces 是从 ViewModelBase 派生的对象的集合。每个 tabitem 代表集合中的项目,因此是 viewmodelbase 派生的对象。

于 2012-09-12T13:20:51.587 回答