【问题标题】:UWP - PointerEntered/PointerExited to simulate mousehover on grid rowsUWP - PointerEntered/PointerExited 模拟鼠标悬停在网格行上
【发布时间】:2017-02-01 12:35:51
【问题描述】:

我已经检查了Simulating a mousehover effect on a fontIcon in uwp。但我面临一个不同的“闪烁”问题。

我在 ScrollViewer 中有一个 Grid,它是 PivotItem 控件的子控件。网格一开始是空的,然后以编程方式填充。

<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>

然后每列填充 3 个文本块。 我的目标是在悬停在一行(而不是单个 TextBlock)上时显示带有附加详细信息的 Flyout。为此,我为每一行定义了一个额外的透明 Rectangle,其 ColumnSpan 为 3,并将其添加为每行的最后一个子元素。然后我给它一个 Flyout,如下所示:

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

这里是 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();
}

当指针进入网格行的点击区域时,突然出现 Flyout 并消失。每当指针移动时,即使在同一行上也是如此(我不希望在将指针移动到同一行上时 Flyout 消失)。结果是闪烁的弹出窗口。在我看来,PointerEntered/PointerExited 事件都会在任何悬停时触发。

我已经尝试过的:

  1. 仅处理 PointerEntered(我知道这不是最佳做法,但我尝试过)
  2. 将 PointerEntered.Handled 设置为 false(我认为网格中的其他控件可能会影响行为)
  3. 仅处理 PointerMoved
  4. 存储“悬停”和“悬停”矩形以识别指针何时位于同一行/另一行上方
  5. 我什至不记得有很多其他尝试...总是得到相同的闪烁结果。

谁能指出我正确的方向?提前谢谢!

【问题讨论】:

    标签: c# xaml uwp flicker flyout


    【解决方案1】:

    在我看来,PointerEntered/PointerExited 事件都会在任何悬停时触发。

    似乎一旦Flyout 出现PointerExited 就会触发,即使鼠标没有离开命中测试区域。如果没有FlyoutPointer 事件可以按照您的想法工作,为此您可以测试official sample

    仅处理 PointerEntered(我知道这不是最佳做法,但我尝试过)

    这种方式应该可以工作,因为没有PointerExited 事件Flyout 不会被隐藏。我还对其进行了测试,Flyout 在单击另一个空间之前不会消失。但正如你所说,这可能不是一个好习惯。

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

    您可以尝试使用ToolTip 的另一种方式。您甚至不需要Pointer 事件,当您悬停该行时,它会显示,当您移出时它会消失。它不会闪烁。虽然一段时间后它会消失,但我认为这足以让你展示细节。

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

    【讨论】:

    • 工具提示的问题是您不能将交互式控件(例如按钮或滑块)放在工具提示中。虽然它与指针和现有行为一起工作得很好,但交互式控件会在您尝试触摸它后导致应用兑现。
    【解决方案2】:

    正如@Sunteen 在之前的回答中指出的那样,弹出按钮将激活 PointerExited 事件。您可以使用 TeachingTip 控件而不是弹出按钮。 TeachingTip 控件不会触发 PointerExited,因此您可以获得悬停效果。请注意,您可能需要添加 TeachingTip 控件。见Implementing TeachingTip control for a 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;
     }
    

    【讨论】:

      猜你喜欢
      • 2018-01-30
      • 2016-07-15
      • 1970-01-01
      • 1970-01-01
      • 2018-10-21
      • 2017-07-03
      • 2010-10-29
      • 2010-11-22
      • 1970-01-01
      相关资源
      最近更新 更多