简体   繁体   English

UWP-PointerEntered / PointerExited在网格行上模拟鼠标悬停

[英]UWP - PointerEntered/PointerExited to simulate mousehover on grid rows

I have already checked Simulating a mousehover effect on a fontIcon in uwp . 我已经检查了对uwp中的fontIcon模拟鼠标悬停效果 But I am facing a different, "flickering" issue. 但是我面临着另一个“闪烁”的问题。

I have a Grid inside a ScrollViewer, which is a child of a PivotItem control. 我在ScrollViewer内部有一个Grid,它是PivotItem控件的子级。 The grid is empty at the beginning and then programmatically populated. 网格在开始时为空,然后以编程方式填充。

<PivotItem>
    <ScrollViewer x:Name="MyScrollBar" >
        <Grid Name="MyGrid">
            <Grid.RowDefinitions>
                 <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                 <ColumnDefinition Width="*"></ColumnDefinition>
                 <ColumnDefinition Width="*"></ColumnDefinition>
                 <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
         </Grid> 
    </ScrollViewer>
</PivotItem>

The columns are then filled with 3 TextBlocks each. 然后,这些列分别填充3个TextBlock。 My goal is to show a Flyout with additional details when hovering over a row (not a single TextBlock). 我的目标是在悬停在一行(而不是单个TextBlock)上时显示具有更多详细信息的弹出窗口。 To achieve this, I define for each row an additional transparent Rectangle whose ColumnSpan is 3, and add it as the last child of each row. 为此,我为每行定义一个附加的透明Rectangle,其ColumnSpan为3,并将其添加为每行的最后一个子级。 I then give it a Flyout as follows: 然后,我将其弹出,如下所示:

Rectangle rect = new Rectangle();
rect.Opacity = 0;
rect.SetValue(Grid.RowProperty, r);
rect.SetValue(Grid.ColumnSpanProperty, 3);
Flyout fl = new Flyout();
Grid flGrid = new Grid();
TextBlock flTb1 = new TextBlock();
flTb1.Text = details.Name;
flGrid.Children.Add(flTb1);
fl.Content = flGrid;
rect.SetValue(FlyoutBase.AttachedFlyoutProperty, fl);
rect.PointerEntered += Rect_PointerEntered;
rect.PointerExited += Rect_PointerExited;
rect.Margin = new Thickness(2);

Here the PointerEntered and PointerExited event handlers: 这里的PointerEntered和PointerExited事件处理程序:

private void Rect_PointerEntered(object sender, PointerRoutedEventArgs e)
{
    ((Flyout)(((Rectangle)sender).GetValue(FlyoutBase.AttachedFlyoutProperty))).ShowAt((Rectangle)sender);
}

private void Rect_PointerExited(object sender, PointerRoutedEventArgs e)
{
    ((Flyout)(((Rectangle)sender).GetValue(FlyoutBase.AttachedFlyoutProperty))).Hide();
}

As the pointer enters the hit zone of a grid row, suddenly the Flyout appears and disappears. 当指针进入网格行的命中区域时,弹出按钮突然出现并消失。 And so it does whenever the pointer moves, even over the same row (I don't want the Flyout to disappear when moving the pointer over the same row). 因此,无论指针何时移动,即使在同一行上也是如此(我不希望将指针移动到同一行上时,Flyout消失)。 The result is a flickering flyout. 结果是闪烁的弹出。 It seemes to me that the PointerEntered/PointerExited events are both fired at any point hovered. 在我看来,PointerEntered / PointerExited事件都在悬停的任何时刻都被触发。

What I have already tried: 我已经尝试过的:

  1. Handle the PointerEntered only (I know this is not best practice, but I tried) 仅处理PointerEntered(我知道这不是最佳实践,但我尝试过)
  2. Set PointerEntered.Handled to false (I thought that maybe the other controls in the grid were impacting the behavior) 将PointerEntered.Handled设置为false(我认为网格中的其他控件可能正在影响行为)
  3. Handle the PointerMoved only 处理指针仅已移动
  4. Stored the "hovered" and "hovering" Rectangle(s) to recognize when the pointer is above the same/another row 存储“悬停”和“悬停”矩形以识别指针何时在同一行/另一行上方
  5. A lot of other attempts I don't even remember... always getting the same flickering results. 我什至不记得很多其他尝试……总是得到相同的闪烁结果。

Could anyone point me in the right direction? 有人能指出我正确的方向吗? Thank you in advance! 先感谢您!

It seemes to me that the PointerEntered/PointerExited events are both fired at any point hovered. 在我看来,PointerEntered / PointerExited事件都在悬停的任何时刻都被触发。

It seems like once the Flyout appears the PointerExited will triggered even the mouse didn't leave the hit test area. 好像一旦Flyout出现在PointerExited会触发连鼠标都没有离开命中测试区域。 Without the Flyout the Pointer events can work as you thought about, for this you can test the official sample . 如果没有“ FlyoutPointer事件可以按照您的想法进行工作,为此,您可以测试官方样本

Handle the PointerEntered only (I know this is not best practice, but I tried) 仅处理PointerEntered(我知道这不是最佳实践,但我尝试过)

This way should be able worked since without PointerExited event the Flyout will not be hidden. 这样应该可以工作,因为没有PointerExited事件的Flyout将不会被隐藏。 I also tested it the Flyout will not disappear until click on another space. 我还测试了它,直到单击另一个空间, Flyout按钮都不会消失。 But as you said this may not be a good practice. 但是正如您所说,这可能不是一个好习惯。

 private void Rect_PointerEntered(object sender, PointerRoutedEventArgs e)
 {
    ((Flyout)(((Rectangle)sender).GetValue(FlyoutBase.AttachedFlyoutProperty))).ShowAt((Rectangle)sender);
 }

 private void Rect_PointerExited(object sender, PointerRoutedEventArgs e)
 {
     //((Flyout)(((Rectangle)sender).GetValue(FlyoutBase.AttachedFlyoutProperty))).Hide();
 }

A another way you can try to use ToolTip . 您可以尝试使用ToolTip另一种方法。 You even don't need Pointer events, when you hovering the row, it will show, and when you move out it will disappear. 您甚至不需要Pointer事件,当您将鼠标悬停在该行上时,它将显示,而当您移出该行时,它将消失。 It will not be flickering. 它不会闪烁。 Although after a time it will disappear but I think it is enough for you showing details. 虽然一段时间后它会消失,但我认为足以显示细节。

 Rectangle rect = new Rectangle();
 rect.Opacity = 0.3;
 rect.SetValue(Grid.RowProperty, r);
 rect.SetValue(Grid.ColumnSpanProperty, 3);
 rect.Fill = new SolidColorBrush(Colors.Azure);  
 Grid flGrid = new Grid();
 TextBlock flTb1 = new TextBlock();
 flTb1.Text = "testname"+r;
 flGrid.Children.Add(flTb1); 
 rect.SetValue(ToolTipService.ToolTipProperty, flGrid); 
 rect.Margin = new Thickness(2);
 MyGrid.Children.Add(rect);

As @Sunteen has pointed out in a previous answer, the flyout will activate a PointerExited event. 正如@Sunteen在上一个答案中指出的那样,弹出按钮将激活PointerExited事件。 You could use a TeachingTip control instead of a flyout. 您可以使用教学提示控件而不是弹出控件。 The TeachingTip control doesn't trigger a PointerExited so you can get the hover-over effect. TeachingTip控件不会触发PointerExited,因此您可以获得悬停效果。 Note you may need to add the TeachingTip control. 请注意,您可能需要添加“教学提示”控件。 See Implementing TeachingTip control for a UWP App 请参阅为UWP App实施教学提示控件

<xmlns:controls="using:Microsoft.UI.Xaml.Controls">
<Image 
    Name="draggable_image"  
    PointerEntered="Draggable_image_PointerEntered"
    PointerExited="Draggable_image_PointerExited"/>       
<controls:TeachingTip 
    x:Name="IconTip"
    Target="{x:Bind draggable_image}"
    PreferredPlacement="Bottom"
    PlacementMargin="10"/>

 private void Draggable_image_PointerEntered(object sender, PointerRoutedEventArgs e) 
 {
     //IconTip.Title = set title 
     //IconTip.Subtitle = set sub title;
     IconTip.IsOpen = true;

 }

 private void Draggable_image_PointerExited(object sender, PointerRoutedEventArgs e)
 {
     IconTip.IsOpen = false;
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM