9

我有一个自定义工具提示样式,它基本上创建了一个漂亮的黑色工具提示,带有一个指向您悬停的项目位置的箭头。

问题是有时工具提示并不总是放置在正确的位置(即靠近窗口边缘),这意味着工具提示箭头不再指向正确的位置......这个问题有什么问题吗?或者我可以为每个位置放置创建特定的样式吗?

<Style x:Key="{x:Type ToolTip}" TargetType="ToolTip">
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="HasDropShadow" Value="True"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToolTip">
                <StackPanel>
                    <Border CornerRadius="3" HorizontalAlignment="Center" VerticalAlignment="Top" Padding="10,7" BorderThickness="0" Background="#e5323232">
                        <StackPanel>
                            <TextBlock FontFamily="Arial" FontSize="12" Text="{TemplateBinding Content}" Foreground="#f0f0f0" />
                        </StackPanel>
                    </Border>
                    <Path Margin="10,0,0,0" Fill="#e5323232" Data="M 0 0 L 6 6 L 12 0 Z"/>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
4

2 回答 2

1

也许你可以试试这个,我只是设置并添加了一个Placement来匹配你在模板中创建的箭头。CenterHorizontalOffset

但是,它不会在控件上垂直居中,因此您可以创建一个IValueConverter并计算控件的大小并除以 2,或者您可以添加一个StackPanel与边框大小相同的虚拟元素,并且应该居中ToolTip 无需任何代码

<Style TargetType="{x:Type ToolTip}">
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="HasDropShadow" Value="True"/>
        <Setter Property="Placement" Value="Center" />
        <!--Offset to the arrow path-->
        <Setter Property="HorizontalOffset" Value="15"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToolTip}">
                    <StackPanel>
                        <Border x:Name="border" CornerRadius="3" HorizontalAlignment="Center" VerticalAlignment="Top" Padding="10,7" BorderThickness="0" Background="#e5323232">
                            <StackPanel>
                                <TextBlock FontFamily="Arial" FontSize="12" Text="{TemplateBinding Content}" Foreground="#f0f0f0" />
                            </StackPanel>
                        </Border>
                        <Path Margin="10,0,0,0" Fill="#e5323232" Data="M 0 0 L 6 6 L 12 0 Z"/>

                        <!--Dummy rectangle same height as tool tip, so it centers on the control-->
                        <Rectangle Height="{Binding ActualHeight, ElementName=border}" />
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
于 2013-05-15T10:23:14.343 回答
0

最简单的方法是使用控件树中存在的 UIElement 作为 Tooltip 的 PlacementTarget。当您靠近窗口边缘时,这将避免 Silverlight 自动定位:

          <StackPanel ToolTipService.ToolTip="{Binding Title, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
                        ToolTipService.Placement="Bottom"
                        ToolTipService.PlacementTarget="{Binding ElementName=LayoutRoot}">                  
                <TextBlock Text="{Binding Title,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
          </StackPanel>

在这种情况下,工具提示将始终定位在 LayoutRoot 元素的原点。如果您有一个固定的路径大小,并且 PlacementTarget 始终相对于您要为其显示工具提示的控件位于相同的位置,那么这可以正常工作。

如果您需要相对于触发工具提示的控件定位工具提示,则每次打开工具提示时,您都必须使路径数据动态并计算距离以在工具提示控件中创建新的路径数据。对于这种情况,您必须处理 Tooltip.IsOpened 事件并实现此逻辑。如果您使用的是 PlacementTarget,那么您总是知道相对于您的控件的方向,因此这使得计算路径顶点变得更加容易。

另一种可行但更复杂的方法是实现您自己的弹出窗口,当您将鼠标移到控件上时会显示该弹出窗口。您需要执行一些计算来获取弹出窗口相对于控件的位置,这正是 Tooltip 控件为您所做的。这样做的好处是您可以完全控制工具提示的位置及其外观。

于 2013-08-21T10:47:19.153 回答