Да, это вообще возможно. Самый простой способ - изменить размещение всплывающей подсказки или настроить задержку показа.
Вы можете управлять поведением всплывающей подсказки, используя ToolTipService
, который предоставляет набор прикрепленных свойств:
<Ellipse Height="25" Width="50"
Fill="Gray"
HorizontalAlignment="Left"
ToolTipService.InitialShowDelay="1000"
ToolTipService.ShowDuration="7000"
ToolTipService.BetweenShowDelay="2000"
ToolTipService.Placement="Right"
ToolTipService.PlacementRectangle="50,0,0,0"
ToolTipService.HorizontalOffset="10"
ToolTipService.VerticalOffset="20"
ToolTipService.HasDropShadow="false"
ToolTipService.ShowOnDisabled="true"
ToolTipService.IsEnabled="true"
ToolTipOpening="whenToolTipOpens"
ToolTipClosing="whenToolTipCloses"
>
<Ellipse.ToolTip>
<BulletDecorator>
<BulletDecorator.Bullet>
<Ellipse Height="10" Width="20" Fill="Blue"/>
</BulletDecorator.Bullet>
<TextBlock>Uses the ToolTipService class</TextBlock>
</BulletDecorator>
</Ellipse.ToolTip>
</Ellipse>
Если это не удовлетворяет вашим требованиям, вы можете вызвать всплывающую подсказку напрямую, установив ToolTiupService.IsEnabled
присоединенное свойство. Это требует обновления фокуса, потому что после того, как подсказка отключена и исчезла, пользователь должен снова вызвать подсказку. По этой причине я бы предпочел вместо этого переключать TooTip.Opacity
.
Другая проблема состоит в том, что фактический столбец не является частью визуального дерева сетки данных.
Чтобы справиться с этим несколько проблематичным c обстоятельством, я ввел свойство stati c для привязки шаблона к нему. Поскольку это свойство stati c и нам нужно уведомление PropertyChanged
(DependencyProperty
не будет работать, поскольку оно связано с экземпляром), я также реализовал версию stati c INotifyPropertyChanged
.
Решение основано на прикрепленном поведении, которое прослушивает перенаправленное событие ScrollViewer.ScrollChanged
для переключения ToolTip.Opacity
через привязку данных:
DataGrid.cs
class DataGrid : DependencyObject, INotifyPropertyChanged
{
#region IsDisableToolTipOnScrollEnabled attached property
public static readonly DependencyProperty IsDisableToolTipOnScrollEnabledProperty = DependencyProperty.RegisterAttached(
"IsDisableToolTipOnScrollEnabled",
typeof(bool),
typeof(DataGrid),
new PropertyMetadata(default(bool), OnIsDisableToolTipOnScrollEnabledChanged));
public static void SetIsDisableToolTipOnScrollEnabled(DependencyObject attachingElement, bool value)
=> attachingElement.SetValue(DataGrid.IsDisableToolTipOnScrollEnabledProperty, value);
public static bool GetIsDisableToolTipOnScrollEnabled(DependencyObject attachingElement)
=> (bool) attachingElement.GetValue(DataGrid.IsDisableToolTipOnScrollEnabledProperty);
#endregion IsDisableToolTipOnScrollEnabled attached property
private static double opacityValue;
public static double OpacityValue
{
get => opacityValue;
set
{
opacityValue = value;
OnStaticPropertyChanged();
}
}
private static DispatcherTimer Timer { get; set; }
static DataGrid()
{
DataGrid.Timer = new DispatcherTimer();
// Set reset tooltip reappearance to 3 seconds
DataGrid.Timer.Interval = TimeSpan.FromSeconds(3);
DataGrid.Timer.Tick += OnTimerElapsed;
DataGrid.OpacityValue = 1.0;
}
private static void OnIsDisableToolTipOnScrollEnabledChanged(DependencyObject attachingElement, DependencyPropertyChangedEventArgs e)
{
if (!(attachingElement is System.Windows.Controls.DataGrid dataGrid))
{
throw new ArgumentException("Attaching element must be of type DataGrid");
}
var behaviorIsEnabled = (bool) e.NewValue;
if (behaviorIsEnabled)
{
EnableScrollHandling(dataGrid);
}
else
{
DisableScrollHandling(dataGrid);
}
}
private static void EnableScrollHandling(System.Windows.Controls.DataGrid dataGrid)
{
if (dataGrid.IsLoaded)
{
dataGrid.AddHandler(ScrollViewer.ScrollChangedEvent, new RoutedEventHandler(OnScrollChanged));
}
else
{
dataGrid.Loaded += (sender, args) =>
dataGrid.AddHandler(ScrollViewer.ScrollChangedEvent, new RoutedEventHandler(OnScrollChanged));
}
}
private static void DisableScrollHandling(System.Windows.Controls.DataGrid dataGrid)
{
dataGrid.RemoveHandler(ScrollViewer.ScrollChangedEvent, new RoutedEventHandler(OnScrollChanged));
}
private static void OnScrollChanged(object sender, RoutedEventArgs e)
{
DataGrid.OpacityValue = 1.0;
// Start or reset the timer on scroll
DataGrid.Timer.Start();
}
private static void OnTimerElapsed(object sender, EventArgs e)
{
var timer = sender as DispatcherTimer;
timer.Stop();
DataGrid.IsToolTipVisible = true;
DataGrid.OpacityValue = 1.0;
}
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
private static void OnStaticPropertyChanged([CallerMemberName] string propertyName = null)
{
DataGrid.StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));
}
}
Использование
<!-- Enable the behavior by setting IsDisableToolTipOnScrollEnabled to true -->
<DataGrid x:Name="DataGrid"
DataGrid.IsDisableToolTipOnScrollEnabled="True">
<DataGrid.Resources>
<!-- Bind the ToolTip.Opacity to the static property of the attached behavior -->
<Style TargetType="ToolTip">
<Setter Property="Opacity" Value="{Binding Path=(viewModels:DataGrid.OpacityValue)}" />
</Style>
</DataGrid.Resources>
<!-- Setup the cell tooltips -->
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="ToolTip" Value="{Binding Value}" />
</Style>
</DataGrid.CellStyle>
</DataGrid>