【问题标题】:Custom ContentControl won't use ContentTemplate from ResourceDictionary自定义 ContentControl 不会使用 ResourceDictionary 中的 ContentTemplate
【发布时间】:2012-07-10 14:25:15
【问题描述】:

我有一个名为 TabItem 的自定义 ContentControl

public class TabItem : ContentControl

我已将 ContentTemplate 设置为来自资源字典的动态资源

<TabItem Header="Search" Content="{Binding Path=SearchRibbon}" ContentTemplate="{DynamicResource SearchRibbonTemplate}" />

使用这种方法,我正在利用 MVVM 设计模式,并且 Content 属性成功地绑定到视图模型的......并且程序成功构建并运行,但没有内容模板应该拉入的数据模板中的内容。

<DataTemplate x:Key="SearchRibbonTemplate">
    <ItemsControl ItemsSource="{Binding}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TabGroupBox Header="{Binding Path=DisplayName}" Width="100">
                    <TabButton Width="100" Icon="{Binding Path=TemplateResource}" LargeIcon="{Binding Path=TemplateResource}" Command="{Binding Path=Commands}" />
                </TabGroupBox>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</DataTemplate>

如果我按原样使用内容控件,这种方法总是有效的。为什么自定义内容控件不能与 ContentTemplate 属性一起使用?

干杯。

编辑

<Style x:Key="RibbonTabItemStyle" TargetType="{x:Type Ribbon_Framework:TabItem}">
    <Style.Triggers>
        <Trigger Property="Group" Value="{x:Null}">
            <Setter Property="BorderBrush" Value="{StaticResource RibbonTopBorderBrush}" />
        </Trigger>
        <Trigger Property="Selector.IsSelected" Value="False">
            <Setter Property="Foreground" Value="{StaticResource TabItemFontBrush}" />
        </Trigger>
    </Style.Triggers>
    <Setter Property="HorizontalAlignment" Value="Left" />
    <Setter Property="VerticalAlignment" Value="Top" />
    <Setter Property="Height" Value="31" />
    <Setter Property="IsMinimized" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Ribbon_Framework:RibbonTabControl}}, Path=IsMinimized, Mode=OneWay, FallbackValue=False}" />
    <Setter Property="IsOpen" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Ribbon_Framework:RibbonTabControl}}, Path=IsDropDownOpen, Mode=OneWay, FallbackValue=True}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Ribbon_Framework:TabItem}">
                <Grid x:Name="grid" Background="#00000000" Height="24" VerticalAlignment="Top" Margin="0,7,0,0">
                    <Border x:Name="border3" Margin="2,0,0,1" BorderThickness="1,0" Grid.ColumnSpan="2">
                        <Border.BorderBrush>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#CCFFFFFF" Offset="0" />
                                <GradientStop Offset="1" Color="#7FFFFFFF" />
                            </LinearGradientBrush>
                        </Border.BorderBrush>
                        <Border x:Name="border4" BorderBrush="{Binding Group.BorderBrush, RelativeSource={RelativeSource TemplatedParent}}" BorderThickness="1,0">
                            <Border.OpacityMask>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="Black" Offset="0" />
                                    <GradientStop Color="#00000000" Offset="0.981" />
                                </LinearGradientBrush>
                            </Border.OpacityMask>
                            <Border Background="{Binding Group.Background, RelativeSource={RelativeSource TemplatedParent}}" BorderThickness="0" Margin="0">
                                <Border.OpacityMask>
                                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                        <GradientStop Color="#59000000" Offset="0" />
                                        <GradientStop Color="#00000000" Offset="1" />
                                    </LinearGradientBrush>
                                </Border.OpacityMask>
                                <Rectangle x:Name="rectangle4" Fill="#3FD2D2D2" StrokeThickness="0">
                                    <Rectangle.OpacityMask>
                                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                            <GradientStop Color="#7F000000" Offset="0" />
                                            <GradientStop Color="#00000000" Offset="1" />
                                        </LinearGradientBrush>
                                    </Rectangle.OpacityMask>
                                </Rectangle>
                            </Border>
                        </Border>
                    </Border>
                    <Grid x:Name="selectedGrid" Visibility="Collapsed" Margin="2,0,0,0" Grid.ColumnSpan="1">
                        <Rectangle x:Name="rectangle" Fill="{StaticResource ActiveTabBackgroundBrush}" Stroke="{x:Null}" StrokeThickness="0" Margin="0" VerticalAlignment="Bottom" Height="1" />
                        <Rectangle x:Name="rectangle1" Fill="{StaticResource ActiveTabBackgroundBrush}" Stroke="{x:Null}" StrokeThickness="0" Margin="1.8,0" VerticalAlignment="Bottom" Height="1.2" />
                        <Rectangle x:Name="rectangle2" Fill="{StaticResource ActiveTabBackgroundBrush}" Stroke="{x:Null}" StrokeThickness="0" Margin="2,0" VerticalAlignment="Bottom" Height="2" />
                        <Border x:Name="border" Margin="1,0,1,2" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" VerticalAlignment="Stretch" CornerRadius="2,2,0,0" Background="{StaticResource ActiveTabBackgroundBrush}">
                            <Border x:Name="border_Copy3" Margin="0" BorderThickness="1,1,1,0" VerticalAlignment="Stretch" CornerRadius="2,2,0,0" Background="{x:Null}" BorderBrush="{StaticResource ActiveTabBackgroundBrush}">
                                <Border x:Name="border_Copy4" Margin="0,0,-2,-1" BorderThickness="0" VerticalAlignment="Stretch" CornerRadius="2,2,0,0" Background="{Binding Group.Background, RelativeSource={RelativeSource TemplatedParent}}" BorderBrush="{x:Null}">
                                    <Border.OpacityMask>
                                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                            <GradientStop Color="#3F000000" Offset="0" />
                                            <GradientStop Color="#00000000" Offset="0.59" />
                                        </LinearGradientBrush>
                                    </Border.OpacityMask>
                                </Border>
                            </Border>
                        </Border>
                        <Border x:Name="border1" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Bottom" Width="2" Height="2" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0,1,1" CornerRadius="0,0,2,0" />
                        <Border x:Name="border2" HorizontalAlignment="Right" Margin="0" VerticalAlignment="Bottom" Width="2" Height="2" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,0,0,1" CornerRadius="0,0,0,2" />
                        <Rectangle x:Name="rectangle3" StrokeThickness="0" Margin="7,-7,7,0" VerticalAlignment="Top" Height="14" IsHitTestVisible="False">
                            <Rectangle.Fill>
                                <RadialGradientBrush Center="0.498,0.501" GradientOrigin="0.498,0.501" RadiusY="0.464">
                                    <GradientStop Color="#7FFFFFFF" Offset="0" />
                                    <GradientStop Offset="1" />
                                </RadialGradientBrush>
                            </Rectangle.Fill>
                        </Rectangle>
                    </Grid>
                    <Grid x:Name="hoverGrid" Margin="2,0,0,0" Visibility="Collapsed" Grid.ColumnSpan="1">
                        <Border x:Name="border_Copy" Margin="1,0,1,1" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" VerticalAlignment="Stretch" CornerRadius="2,2,0,0" Background="{x:Null}">
                            <Border.OpacityMask>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="#CC000000" Offset="0" />
                                    <GradientStop Color="#F7FFFFFF" Offset="0.985" />
                                </LinearGradientBrush>
                            </Border.OpacityMask>
                            <Border x:Name="border_Copy1" Margin="0" BorderBrush="{StaticResource ActiveTabBackgroundBrush}" BorderThickness="1,1,1,0" VerticalAlignment="Stretch" CornerRadius="2,2,0,0" Background="{x:Null}">
                                <Border.OpacityMask>
                                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                        <GradientStop Color="#CCFFFFFF" Offset="0" />
                                        <GradientStop Color="#F7FFFFFF" Offset="1" />
                                    </LinearGradientBrush>
                                </Border.OpacityMask>
                                <Border x:Name="border_Copy2" Margin="0" BorderBrush="{x:Null}" BorderThickness="0" VerticalAlignment="Stretch" CornerRadius="2,2,0,0" Background="{StaticResource ActiveTabBackgroundBrush}">
                                    <Border.OpacityMask>
                                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                            <GradientStop Color="#7FFFFFFF" Offset="0.004" />
                                            <GradientStop Offset="0.5" />
                                        </LinearGradientBrush>
                                    </Border.OpacityMask>
                                </Border>
                            </Border>
                        </Border>
                    </Grid>
                    <Grid x:Name="focusedGrid" Margin="2,0,0,0" Visibility="Collapsed" Grid.ColumnSpan="1">
                        <Grid.OpacityMask>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="White" Offset="0" />
                                <GradientStop Offset="1" Color="#19FFFFFF" />
                            </LinearGradientBrush>
                        </Grid.OpacityMask>
                        <Border x:Name="border_Copy5" Margin="1,0,1,1" BorderThickness="1,1,1,0" VerticalAlignment="Stretch" CornerRadius="2,2,0,0" Background="{StaticResource ButtonHoverOuterBackgroundBrush}" BorderBrush="{StaticResource ButtonHoverOuterBorderBrush}">
                            <Border x:Name="border_Copy6" Margin="0" BorderBrush="{StaticResource ButtonHoverInnerBorderBrush}" BorderThickness="1,1,1,0" VerticalAlignment="Stretch" CornerRadius="2,2,0,0" Background="{StaticResource ButtonHoverInnerBackgroundBrush}" />
                        </Border>
                    </Grid>
                    <Border x:Name="PART_ContentContainer" HorizontalAlignment="Stretch" Margin="6,2,4,2" VerticalAlignment="Stretch" Padding="15,0,0,0" Grid.ColumnSpan="1">
                        <Label x:Name="contentPresenter" AutomationProperties.Name="{TemplateBinding Header}" AutomationProperties.AutomationId="{TemplateBinding Name}" Content="{TemplateBinding Header}" Margin="0, -3, 0,0" HorizontalAlignment="Center" VerticalAlignment="Center" Height="Auto" />
                    </Border>
                    <Grid x:Name="separatorGrid" Margin="0" Visibility="Collapsed" HorizontalAlignment="Right" Width="2" Grid.Column="1">
                        <Rectangle x:Name="separatorRectangle1" Fill="{StaticResource RibbonTopBorderBrush}" Stroke="{StaticResource RibbonTopBorderBrush}" Margin="0,0,1,0" HorizontalAlignment="Right" Width="1" Opacity="1" Visibility="Visible">
                            <Rectangle.OpacityMask>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="#00000000" Offset="0" />
                                    <GradientStop Color="#E5FFFFFF" Offset="0.382" />
                                </LinearGradientBrush>
                            </Rectangle.OpacityMask>
                        </Rectangle>
                        <Rectangle x:Name="separatorRectangle2" Fill="{StaticResource ActiveTabBackgroundBrush}" Stroke="{StaticResource ActiveTabBackgroundBrush}" HorizontalAlignment="Right" Margin="0" Width="1" Opacity="1" Visibility="Visible">
                            <Rectangle.OpacityMask>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="#00000000" Offset="0" />
                                    <GradientStop Color="#BFFFFFFF" Offset="0.329" />
                                </LinearGradientBrush>
                            </Rectangle.OpacityMask>
                        </Rectangle>
                    </Grid>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Opacity" TargetName="contentPresenter" Value="0.5" />
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="HasRightGroupBorder" Value="False" />
                            <Condition Property="HasLeftGroupBorder" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter Property="BorderThickness" TargetName="border3" Value="1,0,0,0" />
                        <Setter Property="BorderThickness" TargetName="border4" Value="1,0,0,0" />
                        <Setter Property="Margin" TargetName="rectangle4" Value="0" />
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="HasLeftGroupBorder" Value="False" />
                            <Condition Property="HasRightGroupBorder" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter Property="BorderThickness" TargetName="border4" Value="0,0,1,0" />
                        <Setter Property="BorderThickness" TargetName="border3" Value="0,0,1,0" />
                        <Setter Property="Margin" TargetName="rectangle4" Value="0" />
                        <Setter Property="Margin" TargetName="border3" Value="0,0,0,1" />
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="HasLeftGroupBorder" Value="False" />
                            <Condition Property="HasRightGroupBorder" Value="False" />
                        </MultiTrigger.Conditions>
                        <Setter Property="BorderThickness" TargetName="border4" Value="0,0,0,0" />
                        <Setter Property="BorderThickness" TargetName="border3" Value="0,0,0,0" />
                        <Setter Property="Margin" TargetName="rectangle4" Value="0" />
                        <Setter Property="Margin" TargetName="border3" Value="0,0,0,1" />
                    </MultiTrigger>
                    <Trigger Property="Group" Value="{x:Null}">
                        <Setter Property="Visibility" TargetName="border3" Value="Collapsed" />
                        <Setter Property="Margin" TargetName="separatorGrid" Value="-1,0,0,1" />
                        <Setter Property="Visibility" TargetName="border_Copy3" Value="Collapsed" />
                        <Setter Property="Visibility" TargetName="rectangle3" Value="Collapsed" />
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Selector.IsSelected" Value="True" />
                            <Condition Property="IsMinimized" Value="False" />
                        </MultiTrigger.Conditions>
                        <Setter Property="Visibility" TargetName="selectedGrid" Value="Visible" />
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True" />
                            <Condition Property="Selector.IsSelected" Value="False" />
                            <Condition Property="IsMinimized" Value="False" />
                        </MultiTrigger.Conditions>
                        <Setter Property="Visibility" TargetName="hoverGrid" Value="Visible" />
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True" />
                            <Condition Property="IsMinimized" Value="True" />
                            <Condition Property="IsOpen" Value="False" />
                        </MultiTrigger.Conditions>
                        <Setter Property="Visibility" TargetName="hoverGrid" Value="Visible" />
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Selector.IsSelected" Value="True" />
                            <Condition Property="IsMinimized" Value="True" />
                            <Condition Property="IsOpen" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter Property="Visibility" TargetName="hoverGrid" Value="Visible" />
                        <Setter Property="Background" TargetName="grid" Value="#00000000" />
                    </MultiTrigger>
                    <Trigger Property="IsSeparatorVisible" Value="True">
                        <Setter Property="Visibility" TargetName="separatorGrid" Value="Visible" />
                        <Setter Property="Margin" TargetName="PART_ContentContainer" Value="6,2" />
                        <Setter Property="Margin" TargetName="hoverGrid" Value="2,0" />
                        <Setter Property="Margin" TargetName="selectedGrid" Value="2,0" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="IsTabStop" Value="False" />
    <Setter Property="Indent" Value="12" />
    <Setter Property="Foreground" Value="{StaticResource TabItemSelectedFontBrush}" />
    <Setter Property="FontFamily" Value="{StaticResource DefaultFontFamily}" />
    <Setter Property="FontSize" Value="{StaticResource DefaultFontSize}" />
    <Setter Property="Margin" Value="0" />
    <Setter Property="BorderBrush" Value="{Binding Group.BorderBrush, RelativeSource={RelativeSource Self}}" />
    <Setter Property="FocusVisualStyle" Value="{StaticResource ControlStyleEmptyFocus}" />
</Style>

【问题讨论】:

  • 您确定您使用的是名为TabItem 的自定义项而不是内置的TabItem 控件吗?标签应该看起来像&lt;local:TabItem&gt;。另外,SearchRibbon 是什么?如果它不是一个可枚举的集合,很可能你的ItemsControl 没有找到任何要渲染的项目,所以最终结果是什么都没有显示。
  • 你绑定到内容的对象是什么类型的?
  • 从技术上讲,您不必为自定义命名空间 @Rachel 设置自定义名称;)
  • 对不起,我删除了本地标签,希望在粘贴时使语法更清晰,但是我忘记了有一个实际的 TabItem,所以我最终让它变得更加混乱......搜索功能区是一个可枚举的MainWindowViewModel 中的集合。
  • @H.B. - 类型是 ReadOnlyCollection SearchRibbon

标签: c# wpf xaml datatemplate


【解决方案1】:

我的猜测是您没有为Themes/Generic.xaml 中的控件定义默认样式,这应该将控件的Template 设置为至少包含ContentPresenter

例如

<Style TargetType="local:TabItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:TabItem">
                 <!-- Usually there is also a Border which template binds the Margin, Padding, etc. -->
                 <ContentPresenter />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

【讨论】:

  • 我在样式的模板属性的值中有一个 ControlTemplate ......你说这应该是一个 ContentPresenter 吗?
  • @bl4kh4k:我说ControlTemplate需要包含一个ContentPresenter,否则Content不会显示。还需要 ControlTemplate 上的 TargetType 才能使 ContentPresenter 绑定到相应的属性。
  • 嗯,所以我在 ControlTemplate 中确实有边框和网格,这种风格......所以我应该将 放在 ControlTemplate 的结束标记之前?我不明白为什么会这样?
  • @bl4kh4k: 不,如我所说,模板需要包含一个ContentPresenter,在哪里无所谓,但是你需要一个,它显示了 TabItem 的内容。
  • 我刚刚用样式更新了我的问题...然后我应该用 ContentPresenter 替换 ControlTemplate 中的 Grid 吗?抱歉,但我仍然不知道该放在哪里?
【解决方案2】:

在与构建我正在改造的 Fluent Ribbon 库的一位开发人员通信后,他指出,为了实现这一设计,需要更多的时间来修改 ContentPresenter,并且需要进行全面的返工。在这种情况下,他建议构建一个从彼此控制派生的 ViewModel 列表将提供我正在寻找的设计。

感谢大家的回答,但在这种情况下,困难的方法似乎是简单的方法。

干杯。

【讨论】:

    猜你喜欢
    • 2018-11-27
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 2017-12-31
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多