【问题标题】:ContentControl Wrapping IssueContentControl 包装问题
【发布时间】:2014-04-17 12:48:26
【问题描述】:

我正在尝试创建自定义工具提示控件。此控件继承自 ToolTip 类。我的自定义工具提示将有一个标题和一个内容区域。内容可以是普通文本或任何其他内容(图像、richtextbox 等)。以下是自定义工具提示控件的模板样式。

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type customControls:FlyoutHelp}">
                <Border BorderThickness="0" Margin="15" Width="300">
                    <Border.Effect>
                        <DropShadowEffect Opacity="0.7"  />
                    </Border.Effect>
                    <StackPanel  TextBlock.FontFamily="Trebuchet MS" TextBlock.FontSize='12'>
                        <TextBlock Background="{StaticResource DellBlue}" Height="23" Foreground="#FFFFFF" Padding="0,4,0,0"  TextAlignment="Center" Text="{Binding HeaderText, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
                        <Border Background="{StaticResource DellLightGrey}" TextBlock.Foreground="{StaticResource DarkestGrey}" Padding="8">
                            <ContentControl   Content="{Binding HelpContent, RelativeSource={RelativeSource Mode=TemplatedParent}}"   />
                        </Border>
                    </StackPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

现在您可以在我的模板中看到我正在使用 ContentControl 来显示工具提示的内容。问题是当我的 HelpContent 只是纯字符串时,它不会包装该文本。我不能用 TextBlock 替换 ContentControl,因为 HelpContent 也可能是其他类型(图像、richtextbox 等)。谁能告诉我解决此问题的最佳方法是什么?我会非常感激的。

【问题讨论】:

    标签: c# .net wpf xaml wpf-controls


    【解决方案1】:

    ContentControl标签替换为:

    <ContentPresenter Content="{TemplateBinding HelpContent}">
        <ContentPresenter.Resources>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="TextWrapping" Value="Wrap"/>
            </Style>
        </ContentPresenter.Resources>
    </ContentPresenter>
    

    [注意:您可以将其保留为ContentControl,但ContentPresenter 更轻且遵循约定]

    【讨论】:

    • 这里使用TemplateBinding相比Binding有什么优势?我以为 TemplateBinding 只是为了继承控件的默认属性。
    • 从赋值的角度来看,TemplateBindingRelativeSource={RelativeSource TemplatedParent}使用正则绑定完全一样。它有一些限制(比如没有Mode=TwoWay 或StringFormat),但最大的优点是它在编译时得到验证——所以,如果你在属性拼写上有错误,在使用TemplateBinding 时会出现构建错误。使用常规绑定构建会成功,但是您会花费很长时间/数小时来找出模板/控件看起来错误的原因。 R# 甚至有助于常规绑定,但 TemplateBinding 更安全。
    【解决方案2】:

    StackPanel 更改为Grid,因为它不知道要换行的宽度。

    <Grid TextBlock.FontFamily="Trebuchet MS" TextBlock.FontSize='12'>
      <Grid.RowDefinitions>
         <RowDefinitions/>
         <RowDefinitions/>
      <Grid.RowDefinitions/>
      <TextBlock Grid.Row="0" Background="{StaticResource DellBlue}" Height="23" Foreground="#FFFFFF" Padding="0,4,0,0"  TextAlignment="Center" Text="{Binding HeaderText, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
      <Border Grid.Row="1" Background="{StaticResource DellLightGrey}" TextBlock.Foreground="{StaticResource DarkestGrey}" Padding="8">
        <ContentControl   Content="{Binding HelpContent, RelativeSource={RelativeSource Mode=TemplatedParent}}"   />
      </Border>
    </Grid>
    

    【讨论】:

    • 默认情况下,StackPanel 具有 Orientation=Horizontal。在这种情况下,StackPanel 在 X 轴上“阻止”其子级,但不在 Y 轴上。所以TextBlock 会“感觉到”边界并且会换行。
    猜你喜欢
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-02
    • 2015-07-09
    • 2016-03-13
    相关资源
    最近更新 更多