ScrollViewer and ToolTip

1.6k views Asked by At

I have xaml:

<Grid>
    <ScrollViewer x:Name="svViewer" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Hidden" Grid.Column="0" Grid.Row="0">
        <Border>
            <ItemsControl x:Name="svItemControl" VerticalAlignment="Stretch" MouseWheel="svViewer_MouseWheel">

            </ItemsControl>
        </Border>
    </ScrollViewer>
</Grid>

and a code for it:

public partial class MainWindow : Window
{

    double Friction;
    private DispatcherTimer animationTimer = new DispatcherTimer();
    double scrollVelocity;
    double scrollOffset;
    const double c_vel_colors = 8;
    public MainWindow()
    {
        InitializeComponent();

        Friction = 0.9;
        InitializeComponent();
        loadContent();

        animationTimer.Interval = new TimeSpan(0, 0, 0, 0, 5);
        animationTimer.Tick += new EventHandler(HandleWorldTimerTick);
        animationTimer.Start();
    }

    private void HandleWorldTimerTick(object sender, EventArgs e)
    {
        if (Math.Abs(scrollVelocity) > 1)
        {
            svViewer.ScrollToVerticalOffset(scrollOffset);
            scrollOffset += scrollVelocity;
            scrollVelocity *= Friction;
        }
    }

    public void svViewer_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        scrollVelocity = (e.Delta > 0) ? -1 * (c_vel_colors) : (c_vel_colors);
        scrollOffset = svViewer.VerticalOffset + scrollVelocity;
    }

    void loadContent()
    {
        StackPanel sp2 = new StackPanel();
        sp2.Orientation = Orientation.Vertical;

        Rectangle[] rc = new Rectangle[50];
        Random rnd = new Random();
        SolidColorBrush _brush;

        for (int i = 0; i < rc.Length; i++)
        {
            _brush = new SolidColorBrush(Color.FromArgb((byte)255, (byte)rnd.Next(0, 255), (byte)rnd.Next(0, 255), (byte)rnd.Next(0, 255)));
            rc[i] = new Rectangle(); rc[i].Height = 50; rc[i].Width = 50;
            rc[i].Fill = _brush;

            StackPanel sp_tt_Colors = new StackPanel();
            Rectangle tt_Rect = new Rectangle
            {
                Fill = _brush,
                Width = 100,
                Height = 100
            };

            TextBlock tb = new TextBlock
            {
                Foreground = new SolidColorBrush(Color.FromArgb((byte)255, (byte)255, (byte)255, (byte)255)),
                FontSize = 12,
                Text = i.ToString()
            };

            sp_tt_Colors.Children.Add(tt_Rect);
            sp_tt_Colors.Children.Add(tb);

            ToolTip tt = new ToolTip();
            ToolTipService.SetIsEnabled(rc[i], true);
            ToolTipService.SetBetweenShowDelay(rc[i], 1000);
            ToolTipService.SetInitialShowDelay(rc[i], 1000);

            tt.Content = sp_tt_Colors;
            tt.Background = new SolidColorBrush(Color.FromArgb((byte)32, (byte)10, (byte)10, (byte)245));

            rc[i].ToolTip = tt;
            sp2.Children.Add(rc[i]);
            i++;
        }

        svItemControl.Items.Add(sp2);
    }
}

The goal is to Scroll this list with colored rectangles, I have own eventhandler for MouseWheeel - ScrollViewer scrolls smoothly in both sides. And every rectangle has own ToolTip (oversized color rectangle).

So, the questions are:

  1. While scrolling except my eventhandler there is standart eventhandler for scrollviewer works, so you can see shaking in start of scroll. How to turn off standart eventhandler?

  2. Even I setted properties ToolTipService.SetBetweenShowDelay and ToolTipService.SetInitialShowDelay, ToolTip doesn't work as I expect. Delay works only first time. After first time ToolTip appears immidiatelly. So, while scrolling ToolTip appears again and again and that is the reason of slow and non-smooth working. How to deal with it?

Thank you!

2

There are 2 answers

2
Marc On

For wasting the old eventhandler you have to create a custom control with overriden events like this example for a WPF TextBox.

class TextBoxA : TextBox
{
    protected override void OnTouchUp(System.Windows.Input.TouchEventArgs e)
    {
        base.OnTouchUp(e);
    }
}

Simply replace ur used control with the new one.. Should work.

2
almulo On
  1. Use e.Handled = true in your svViewer_MouseWheel event handler, to specify that you want to handle that event instead of letting the ScrollViewer handle it.

  2. Clueless about this one... I guess it should work, though you're setting a delay of only 1 second, which isn't really a lot longer than the default value (0.4 seconds).