XamNumericSlider のつまみに XamSliderNumericThumb.ToolTipTemplate でツールチップを設定しても、つまみをドラッグしている間は消えてしまいます。ドラッグ中も値を表示し続けるには、ツールチップの代わりに WPF の Popup を使い、PreviewMouseMove イベントでつまみの上に表示します。
XamNumericSlider の設定
XamNumericSlider に、つまみの上でマウスが動いたことを検知する PreviewMouseMove イベントと、スライダーからマウスが離れたことを検知する MouseLeave イベントのハンドラーを設定します。
<ig:XamNumericSlider x:Name="xamNumericSlider1" ...
MinValue="0" MaxValue="100" TrackClickAction="MoveToPoint"
PreviewMouseMove="xamNumericSlider1_PreviewMouseMove"
MouseLeave="xamNumericSlider1_MouseLeave">
</ig:XamNumericSlider>
次に、ツールチップとして表示する Popup を定義します。Placement="Custom" と CustomPopupPlacementCallback で表示位置をコードから決められるようにします。TextBlock は XamNumericSlider の Value にバインドしているので、ドラッグに合わせて表示値が更新されます(このサンプルでは IValueConverter で値を整数に丸めています)。IsHitTestVisible="False" を指定し、Popup がマウス操作を妨げないようにします。
<Popup Name="floatingTip"
AllowsTransparency="True"
Placement="Custom"
CustomPopupPlacementCallback="FloatingTip_CustomPopupPlacementCallback"
IsHitTestVisible="False">
<StackPanel Orientation="Vertical">
<Border ...>
<TextBlock Text="{Binding ElementName=xamNumericSlider1, Path=Value, Converter={StaticResource MyConverter}}" ... />
</Border>
<Polygon Points="0,0 10,0 5,6" Fill="#FF2B2B2B" HorizontalAlignment="Center" ... />
</StackPanel>
</Popup>
PreviewMouseMove イベントでの Popup の表示
PreviewMouseMove イベントで、マウス カーソルの下にある要素(Mouse.DirectlyOver)から Utilities.GetAncestorFromType(Infragistics.Windows 名前空間)を使って親をたどり、つまみの XamSliderNumericThumb を取得します。つまみが見つかった場合は、それを Popup の PlacementTarget に設定して IsOpen = true で表示します。見つからない場合は Popup を閉じます。PreviewMouseMove はドラッグ中も発生するため、ToolTip と違ってドラッグ中も表示が消えません。
private void xamNumericSlider1_PreviewMouseMove(object sender, MouseEventArgs e)
{
var thumb = Utilities.GetAncestorFromType(Mouse.DirectlyOver as DependencyObject, typeof(XamSliderNumericThumb), false) as XamSliderNumericThumb;
var activeThumb = thumb ?? Mouse.DirectlyOver as XamSliderNumericThumb;
if (activeThumb != null)
{
if (!ReferenceEquals(floatingTip.PlacementTarget, activeThumb))
{
floatingTip.PlacementTarget = activeThumb;
}
if (!floatingTip.IsOpen)
{
floatingTip.IsOpen = true;
}
}
else
{
floatingTip.IsOpen = false;
}
}
CustomPopupPlacementCallback では、Popup がつまみの中央真上に来るように表示位置を計算して返します。また、MouseLeave イベントで、マウスがスライダーから離れたら Popup を閉じます。
private CustomPopupPlacement[] FloatingTip_CustomPopupPlacementCallback(Size popupSize, Size targetSize, Point offset)
{
var placementPoint = new Point(
(targetSize.Width - popupSize.Width) / 2d,
-popupSize.Height - 2d);
return [new CustomPopupPlacement(placementPoint, PopupPrimaryAxis.None)];
}
private void xamNumericSlider1_MouseLeave(object sender, MouseEventArgs e)
{
floatingTip.IsOpen = false;
}
実行結果
つまみにマウスを乗せると、つまみの上に現在の値が表示されます。つまみをドラッグしている間も表示は消えず、値がリアルタイムに更新されます。
