如何从绑定ObervableCollection更改为TabControl到ContentControl

时间:2012-04-16 12:12:04

标签: wpf

我是WPF的新手,我正在编写一个使用此示例作为起点的应用程序 http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090025

我任何时候都只能看到一个工作区,所以我想摆脱TabControl并使用一些简单的东西 - 可能是一个ContentControl,我真的不确定但是它需要做的就是有内容并且可以关闭所以我试图取代它:

<DataTemplate x:Key="WorkspacesTemplate"><TabControl 
  IsSynchronizedWithCurrentItem="True" 
  ItemsSource="{Binding}" 
  ItemTemplate="{StaticResource ClosableTabItemTemplate}"
  Margin="4"
  />

使用:

<DataTemplate x:Key="WorkspacesTemplate">
    <ContentControl Content="{Binding ??}" ContentTemplate="{StaticResource ClosableTabItemTemplate}"/>
</DataTemplate>

但我不知道要绑定什么。示例中的代码似乎使用CollectionViewSource来设置活动工作区 - 它是我感兴趣的活动工作区但我不明白TabControl正在做什么,除了它与IsSynchronizedWithCurrentItem =“True”有关

从这里调用模板(Workspaces是ViewModels的ObservableCollection):

<HeaderedContentControl Content="{Binding Path=Workspaces}" ContentTemplate="{StaticResource   WorkspacesTemplate}" Header="Workspaces" Style="{StaticResource MainHCCStyle}"/>

这是ClosableItem模板:

  <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>

请有人解释我需要做什么吗?感谢

1 个答案:

答案 0 :(得分:2)

WorkspacesTemplate告诉WPF如何显示Workspaces属性,正如您所说的那样是ViewModel的ObservableCollection

因此,WorkspacesTemplate表示,在选项卡控件中显示所有这些ViewModel,并且对于每个ViewModel,使用ClosableTabItemTemplate在选项卡中显示ViewModel。

由于您一次只能看到一个工作区,因此您不需要从ViewModel公开工作区集合,也不需要使用选项卡控件来显示它们。您只需从ViewModel公开一个当前工作空间,并提供一些XAML来显示它。

如果您仍想使用模板来包装ViewModel,那么是的,您可以使用ContentControl来调用模板:

<DataTemplate x:Key="MySingleWorkspaceTemplate">
    <TextBlock Text={Binding Blah} />
    <!-- etc -->
</DataTemplate>

并调用模板

<ContentControl Content="{Binding CurrentWorkspace}" ContentTemplate="{StaticResource MySingleWorkspaceTemplate}"/>

但是,如果这是XAML将被使用的唯一地方,您可能会忘记模板并直接声明XAML。例如,(而不是ContentControl)

<TextBlock Text={Binding CurrentWorkspace.Blah} />
<!-- etc -->

已编辑添加:

我认为您可能会感到困惑,因为目前ViewModel没有“选定工作区”的概念,它只是暴露了一个集合。为了完整性(但不要担心所有这些),TabControl引入了选择,CollectionView间接使用Workspaces集合的默认CollectionViewContentTemplate所选项目的概念。这一切都在视野中。

我现在不用担心这一点,只需从ViewModel公开一个工作区。

<强> EDIT2:

您的关闭按钮正在显示,因为您在HeaderedContentControl上明确设置了Content。无论Content如何,都会显示此模板。

要仅在DataType中有数据时才显示模板,请隐式设置模板。如果向模板定义中添加<DataTemplate DataType="{x:Type vm:WorkspaceViewModel}"> <!-- Blah --> </DataTemplate> (并删除键),则告诉WPF始终使用此模板显示该数据类型的对象。

HeaderedContentControl

然后,您可以从Content中删除显式模板。只需设置<HeaderedContentControl Content="{Binding Path=CurrentWorkspace}" /> 即可调用模板,如果没有内容,则没有模板。

HeaderedContentControl

(ps。如果你没有使用ContentControl的标题,你也可以使用沼泽标准{{1}})