2

我像 Outlook 2007 一样创建了 NavigationPane。在 Outlook 中,当窗格折叠并单击侧栏时,它会弹出 Selected NavigationItem 内容。我在 ControlTemplete 中使用 contentpresenter 模仿了相同的行为(一个用于 TabControl 的 SelectItemHost,另一个用于 Popup)。但问题是当弹出窗口打开时,NavigationPane 在离开时选择了内容,当我们从另一个导航项切换回同一个导航项时它会出现。我使用 TabControl 和 TabItem 作为 NavigationPane 和 NavigationPaneItem。

我将“SelectedContent”指向两个 ContentPresenter 的 ContentSource

4

1 回答 1

5

您可以在控件模板中定义两个ContentPresenter对象,并将它们都指向同一内容源(如果您愿意):

<ControlTemplate x:Key="WeirdButton" TargetType="Button">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Border Grid.RowSpan="2" Background="{TemplateBinding Background}" />
        <ContentPresenter ContentSource="Content"/>
        <ContentPresenter ContentSource="Content" Grid.Row="1"/>
    </Grid>
</ControlTemplate>

然而,这有一些相当不寻常的副作用。因为您不能将相同的视觉对象放在视觉对象树中的两个位置,所以该模板仅在按钮的子内容不是视觉对象(或从视觉对象派生)时才能按预期工作。如果内容是其他类型的数据,并且视觉效果是由数据模板生成的,那么一切都会按预期工作。将按钮的内容设置为字符串 ( <Button Content="OK"/>) 也可以。

请注意,可以使用视觉画笔来实现相同的效果:

<ControlTemplate x:Key="WeirdButton" TargetType="Button">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Border Grid.RowSpan="2" Background="{TemplateBinding Background}" />
        <ContentPresenter x:Name="presenter" ContentSource="Content"/>
        <Rectangle Grid.Row="1" 
                   Width="{Binding ActualWidth, ElementName=presenter}" Height="{Binding ActualHeight, ElementName=presenter}">
            <Rectangle.Fill>
                <VisualBrush Visual="{Binding ElementName=presenter}" Stretch="None" AlignmentX="Left"/>
            </Rectangle.Fill>
        </Rectangle>
    </Grid>
</ControlTemplate>

这种方法的缺点是您无法与视觉画笔中的控件进行交互。因此,如果您希望副本上的按钮、文本框和其他控件也具有交互性,则必须采用更接近第一个模板的方法。

于 2011-05-13T13:12:38.523 回答