WPF Tooltip позиционирование - PullRequest
6 голосов
/ 13 марта 2012

У меня есть стиль в моей подсказке 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>

1 Ответ

7 голосов
/ 11 июня 2013

Стандартный стиль WPF для Windows 7

Standard WPF Windows 7 style

Стандартные позиции всплывающей подсказки WPF на указателе мыши, которые, на мой взгляд, выглядят идеально.

Изображение ниже иллюстрирует вашу проблему

Styled ToolTip with no code-behind

Если вы действительно хотите сделать то, что вы просите, это возможно: вам нужен код настиль для вычисления горизонтальной корректировки, поместите его в ToolTip.Tag и привяжите границу заостренной части к вычисленной корректировке:

Пересмотренный стиль всплывающей подсказки -

    <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);
}

Это отвечает на ваш вопрос в соответствии с заданным вопросом,

Styled ToolTip - Top Right

, но этого недостаточно, когда всплывающая подсказка находится в нижней части экрана:

Styled ToolTip - Bottom Right

Чтобы исправить это, вы можете изменить выделенный код, чтобы определить, что всплывающая подсказка находится над целью, и установить для всплывающей подсказки «Положение сверху», а всплывающее окно «Свойство триггера свойств» стилизовать всплывающую часть под прямоугольником -

Полный 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);
}

Окончательный результат

Final result - Top left

Final fixed result - Bottom right

Заостренная часть теперь регулируется по горизонтали, когда всплывающая подсказка находится ближе к правой части экрана, и по вертикали, когда подсказка приближается к нижней части экрана.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...