Silverlight工具提示样式ContentPresenter TextWrapping

时间:2012-06-12 15:48:46

标签: silverlight styles tooltip textwrapping contentpresenter

我想创建Silverlight工具提示样式,但我不想使用文本块,因为工具提示内容可能是图像或其他内容。所以我使用的是ContentPresenter。我的问题是如何设置MaxWidth并在内容为文本时强制TextWrapping。这就是我到目前为止所做的:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">

    <Style TargetType="ToolTip">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ToolTip">
                    <Border BorderBrush="DimGray" BorderThickness="1" CornerRadius="5" Background="WhiteSmoke" Opacity="0.8"
                        HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,10,0,-5" Width="Auto">
                        <Border.Effect>
                            <DropShadowEffect BlurRadius="16" ShadowDepth="8" Direction="-45" Color="Black" Opacity="0.6"/>
                        </Border.Effect>
                        <Grid>
                            <ContentPresenter Content="{TemplateBinding Content}" Margin="3"/>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

2 个答案:

答案 0 :(得分:0)

我找到了一种方法: 创建2个工具提示样式 - 一个用于文本,另一个用于其他一切,如下所示:

<Style x:Key="TooltipStyleForText" TargetType="ToolTip">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToolTip">
                <Border BorderBrush="DimGray" BorderThickness="1" CornerRadius="5" Background="WhiteSmoke" Opacity="0.8"
                    HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,10,0,-5" Width="Auto">
                    <Border.Effect>
                        <DropShadowEffect BlurRadius="16" ShadowDepth="8" Direction="-45" Color="Black" Opacity="0.6"/>
                    </Border.Effect>
                    <Grid>
                        <TextBlock Text="{TemplateBinding Content}" MaxWidth="400" TextWrapping="Wrap" Margin="3"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="TooltipStyleForOtherStuffThanText" TargetType="ToolTip">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToolTip">
                <Border BorderBrush="DimGray" BorderThickness="1" CornerRadius="5" Background="WhiteSmoke" Opacity="0.8"
                    HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,10,0,-5" Width="Auto">
                    <Border.Effect>
                        <DropShadowEffect BlurRadius="16" ShadowDepth="8" Direction="-45" Color="Black" Opacity="0.6"/>
                    </Border.Effect>
                    <Grid>
                        <ContentPresenter Content="{TemplateBinding Content}" Margin="3"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

并且比我们使用TextBlock时,将其称为ToolTip样式,如下所示:

<TextBlock Text="something">
    <ToolTipService.ToolTip>
        <ToolTip Style="{StaticResource TooltipStyleForText}">
            <TextBlock Text="Some text"/>
        </ToolTip>
    </ToolTipService.ToolTip>
</TextBlock>

这可能不是最佳解决方案,因为我们有两种样式,因此我们需要为简单的TextBlock指定写几行。 我希望有人有更好的解决方案。

答案 1 :(得分:0)

在设置以下解决方案之前,我们需要做同样的事情并尝试一些方法。问题是,当ToolTip.Content是一个字符串时,您需要使用TextBlock显示工具提示。当ToolTip.Content不是字符串时,您需要使用ContentPresenter。所以我们最终定义了一个包含两者的ControlTemplate,并根据ToolTip.Content的类型显示/隐藏了相应的一个。此方法适用于应用程序中的所有工具提示:

以下转换器类可以帮助解决这个问题:

public class TooltipContentVisibilityConverter : IValueConverter
{
    public Visibility VisibilityWhenToolTipContentIsAString { get; set; }
    public Visibility VisibilityWhenToolTipContentIsNotAString { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var toolTip = value as ToolTip;
        if (toolTip != null && toolTip.Content is string)
        {
            return VisibilityWhenToolTipContentIsAString;
        }

        return VisibilityWhenToolTipContentIsNotAString;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

然后在App.xaml中定义以下内容。

<Converter:TooltipContentVisibilityConverter VisibilityWhenToolTipContentIsAString="Visible" VisibilityWhenToolTipContentIsNotAString="Collapsed" x:Key="tooltipStringContentVisibilityConverter" />
<Converter:TooltipContentVisibilityConverter VisibilityWhenToolTipContentIsAString="Collapsed" VisibilityWhenToolTipContentIsNotAString="Visible" x:Key="tooltipNonStringContentVisibilityConverter" />
    <Style TargetType="ToolTip">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ToolTip">
        <Border CornerRadius="0" Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1" Padding="4">
          <StackPanel Orientation="Vertical">
            <TextBlock Text="{TemplateBinding Content}" TextWrapping="Wrap" MaxWidth="300" 
                       Visibility="{Binding RelativeSource={RelativeSource AncestorType=ToolTip},Converter={StaticResource tooltipStringContentVisibilityConverter}}"/>
            <ContentPresenter Content="{TemplateBinding Content}" 
                              Visibility="{Binding RelativeSource={RelativeSource AncestorType=ToolTip},Converter={StaticResource tooltipNonStringContentVisibilityConverter}}"/>
          </StackPanel>
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
    </Style>

似乎有点尴尬的方法来解决这个问题,但它确实有效,我们还没有找到更好的解决方案。