【问题标题】:WPF Tooltip positioningWPF 工具提示定位
【发布时间】:2012-03-12 20:41:16
【问题描述】:

我的 WPF 工具提示上有一个样式,基本上使它看起来像一个气泡。当控件位于窗口右侧时,气泡的尖端部分会停止正确对齐,因为 WPF 会重新对齐工具提示以适应窗口。是否可以根据工具提示的定位方式应用不同的样式?

我的 XAML 如下所示:

<Style x:Key="MyToolTip" TargetType="{x:Type ToolTip}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToolTip}">
                <Grid x:Name="Grid">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="20" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <Rectangle Fill="#fff" Stroke="#FF000000" RadiusX="4" RadiusY="4" Grid.Row="1" />
                    <Path Fill="#fff" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" Margin="8,0,0,-1.5" Width="20" Grid.Row="0"
                        Data="M 0,21 L 10,0 20,21" />
                    <ContentPresenter Margin="8" Grid.Row="1" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Placement" Value="Bottom" />
    <Setter Property="HorizontalOffset" Value="-2" />
    <Setter Property="Width" Value="250" />
    <Setter Property="Height" Value="Auto" />
</Style>

【问题讨论】:

  • 我要触发什么属性?
  • @sohum 你有想过这个吗?

标签: wpf xaml styles tooltip


【解决方案1】:

标准 WPF Windows 7 样式

标准的 WPF 工具提示定位在鼠标指针上,我认为这看起来很完美。

下图说明了您的问题

如果你真的想按照你的要求做,有可能:你需要在样式上的代码隐藏来计算水平调整,把它放到 ToolTip.Tag 中,并将尖部分边框绑定到计算的调整:

修改了 ToolTip 样式 -

    <Style TargetType="{x:Type ToolTip}">
        <!-- As before, except Margin of the pointy part is now bound to calculated ToolTip.Tag -->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToolTip}">
                    <Grid x:Name="Grid">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="20" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <Rectangle Fill="#fff" Stroke="#FF000000" RadiusX="4" RadiusY="4" Grid.Row="1" />
                        <Path Fill="#fff" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" 
                              Margin="{TemplateBinding Tag}" Width="20" Grid.Row="0"
                    Data="M 0,21 L 10,0 20,21" />
                        <ContentPresenter Margin="8" Grid.Row="1" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Placement" Value="Bottom" />
        <!-- Event to adjust horizontal position of the pointy part -->
        <EventSetter Event="Opened" Handler="ToolTipOpenedHandler" />
    </Style>

代码隐藏

private void ToolTipOpenedHandler(object sender, RoutedEventArgs e)
{
    ToolTip toolTip = (ToolTip) sender;
    UIElement target = toolTip.PlacementTarget;
    Point adjust = target.TranslatePoint(new Point(8, 0), toolTip);
    toolTip.Tag = new Thickness(adjust.X, 0, 0, -1.5);
}

这回答了你的问题,

但当工具提示靠近屏幕底部时还不够:

要解决此问题,您可以修改代码隐藏以检测工具提示位于目标上方并将工具提示位置设置为顶部,并使用属性触发器样式设置工具提示,使其尖部分位于矩形下方 -

完整的 XAML(包括宽、窄和多行提示)

<Window x:Class="WpfToolTip.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="MainWindow" Height="250" Width="250">
    <Window.Resources>
        <Style TargetType="{x:Type ToolTip}">
            <!-- As before, except Margin of the pointy part is now bound to calculated ToolTip.Tag -->
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ToolTip}">
                        <Grid x:Name="Grid">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="20" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>
                            <Rectangle MinWidth="40" Fill="#fff" Stroke="#FF000000" RadiusX="4" RadiusY="4" Grid.Row="1" />
                            <Path Fill="#fff" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" 
                                  Margin="{TemplateBinding Tag}" Width="20" Grid.Row="0"
                        Data="M 0,21 L 10,0 20,21" />
                            <ContentPresenter Margin="8" Grid.Row="1" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Placement" Value="Bottom" />
            <!-- Event to adjust horizontal position of the pointy part -->
            <EventSetter Event="Opened" Handler="ToolTipOpenedHandler" />
            <Style.Triggers>
                <Trigger Property="Placement" Value="Top">
                    <!-- When placement is Top, place the pointy part below the rectangle part -->
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ToolTip}">
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*" />
                                        <RowDefinition Height="20" />
                                    </Grid.RowDefinitions>
                                    <Rectangle MinWidth="40" Fill="#fff" Stroke="#FF000000" RadiusX="4" RadiusY="4" Grid.Row="0" />
                                    <Path Fill="#fff" Stretch="None" Stroke="#FF000000" HorizontalAlignment="Left" Width="20" Grid.Row="1" 
                                        Data="M 0,0 L 10,20 20,0" Margin="{TemplateBinding Tag}" />
                                    <ContentPresenter Margin="8" Grid.Row="0" />
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <TextBlock VerticalAlignment="Top" HorizontalAlignment="Left" Background="Aqua" ToolTipService.ToolTip="ToolTip for TopLeft - MMMMMMMMMWWWWWWWWWW">TopLeft</TextBlock>
        <TextBlock VerticalAlignment="Top" HorizontalAlignment="Right" Background="Aqua" ToolTipService.ToolTip="ToolTip for TopRight - MMMMMMMMMWWWWWWWWWW">TopRight</TextBlock>
        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Background="Aqua" ToolTipService.ToolTip="i">CenterLeft</TextBlock>
        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Right" Background="Aqua" ToolTipService.ToolTip="i">CenterRight</TextBlock>
        <TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Left" Background="Aqua" Text="BottomLeft">
            <TextBlock.ToolTip>
                <TextBlock>Multi-line ToolTip for Bottomleft - MMMMMMMMMWWWWWWWWWW<LineBreak/>x<LineBreak/>y<LineBreak/>z</TextBlock>
            </TextBlock.ToolTip>
        </TextBlock>
        <TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Right" Background="Aqua" ToolTipService.ToolTip="ToolTip for BottomRight - MMMMMMMMMWWWWWWWWWW">BottomRight</TextBlock>
    </Grid>
</Window>

代码隐藏

private void ToolTipOpenedHandler(object sender, RoutedEventArgs e)
{
    ToolTip toolTip = (ToolTip)sender;
    UIElement target = toolTip.PlacementTarget;
    Point adjust = target.TranslatePoint(new Point(8, 0), toolTip);
    if (adjust.Y > 0)
    {
        toolTip.Placement = PlacementMode.Top;
    }
    toolTip.Tag = new Thickness(adjust.X, -1.5, 0, -1.5);
}

最终结果

当工具提示靠近屏幕右侧时,尖头部分现在水平调整,当工具提示靠近屏幕底部时垂直调整。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    • 2011-06-17
    • 2010-10-22
    • 1970-01-01
    相关资源
    最近更新 更多