I have already checked Simulating a mousehover effect on a fontIcon in uwp. But I am facing a different, "flickering" issue.
I have a Grid inside a ScrollViewer, which is a child of a PivotItem control. 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. My goal is to show a Flyout with additional details when hovering over a row (not a single 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. 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:
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). The result is a flickering flyout. It seemes to me that the PointerEntered/PointerExited events are both fired at any point hovered.
What I have already tried:
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.
It seems like once the Flyout
appears the PointerExited
will triggered even the mouse didn't leave the hit test area. Without the Flyout
the Pointer
events can work as you thought about, for this you can test the official sample.
Handle the PointerEntered only (I know this is not best practice, but I tried)
This way should be able worked since without PointerExited
event the Flyout
will not be hidden. I also tested it the Flyout
will not disappear until click on another space. 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
. You even don't need Pointer
events, when you hovering the row, it will show, and when you move out it will disappear. 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);