Search code examples
wpfscrollpdfnet

Scrolling in Sticky Notes


I got the following sticky note example:

enter image description here

If the sticky note has more than 9 rows, the additional rows are not visible. I'm able to navigate through the note with my arrow keys. If I'm going to scroll with the mouse wheel, it seems to ignore the popup and just changes the page.

Is it possible to activate scrolling for sticky note popups?


Solution

  • Edit:The solution outlined below will soon be available as part of the samples included in the PDFTron SDK download. In the meanwhile, I hope that the below solution helps.

    Yes, it is possible to activate scrolling for sticky notes.

    The problem is most apparent when using the single page view. It appears to work as expected in continuous mode.

    However it is not as simple as setting VerticalScrollVisibility = ScrollBarVisibility.Auto;. There are a few files that need to be modified to get this working.

    The good news is that we can get the expected behaviour by modifying the code in the provided samples.

    Solution

    The solution is to add some handling for the PreviewMouseWheel event coming from the PDFViewWPF class.
    In the downloaded samples, the following changes were made to get things running as expected:

    • Add a method to handle the PreviewMouseWheel event in the NoteHost class (Samples/PDFViewWPFTools/CS/Utilities/NoteHost.cs)

      internal void HandlePreviewMouseWheel(object sender, MouseWheelEventArgs e)
      {
          var originalSource = (UIElement)e.OriginalSource;
          if (originalSource.IsDescendantOf(mNoteBorder) && mTextBox.IsFocused)
          {
              mTextBox.ScrollToVerticalOffset(mTextBox.VerticalOffset - e.Delta);
              e.Handled = true;
          }
      }
      
    • Also make sure to add mTextBox.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; in the NoteHost.CreateNoteAndArrow() method, after the mTextBox object is instantiated (~line 183).
    • Next, edit the NoteManager class - Samples/PDFViewWPFTools/CS/Utilities/NoteManager.cs - and add a HandlePreviewMouseWheel method. This will internally call the HandlePreviewMouseWheel on each displayed (opened) note and break at the first one where the event gets handled.

      internal void HandlePreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
      {
          foreach(var note in mActiveNotes)
          {
              note.Value.HandlePreviewMouseWheel(sender, e);
              if(e.Handled)
              {
                  break;
              }
          }
      }
      
    • Next, edit the ToolManager class to ensure that the note manager gets a chance to handle the PreviewMouseWheel before attempting a page change. Open Samples/PDFViewWPFTools/CS/ToolManager.cs and navigate to the PDFView_PreviewMouseWheel. The existing method should look like this:

      private void PDFView_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
      {
          if (mCurrentTool != null && _IsEnabled)
          {
              ToolManager.ToolType prev_tm = mCurrentTool.ToolMode;
              ToolManager.ToolType next_tm;
              while (true)
              {
                  mCurrentTool.PreviewMouseWheelHandler(sender, e);
                  next_tm = mCurrentTool.NextToolMode;
                  if (prev_tm != next_tm)
                  {
                      mCurrentTool = CreateTool(next_tm, mCurrentTool);
                      prev_tm = next_tm;
                  }
                  else
                  {
                      break;
                  }
              }
          }
      }
      

      Replace it with the below code:

      private void PDFView_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
      {
          if (mCurrentTool != null && _IsEnabled)
          {
              ToolManager.ToolType prev_tm = mCurrentTool.ToolMode;
              ToolManager.ToolType next_tm;
              while (true)
              {
                  mNoteManager.HandlePreviewMouseWheel(sender, e);
                  if (!e.Handled)
                  {
                      mCurrentTool.PreviewMouseWheelHandler(sender, e);
                      next_tm = mCurrentTool.NextToolMode;
                      if (prev_tm != next_tm)
                      {
                          mCurrentTool = CreateTool(next_tm, mCurrentTool);
                          prev_tm = next_tm;
                      }
                      else
                      {
                          break;
                      }
                  }
                  else
                  {
                      break;
                  }
              }
          }
      }
      

    By doing the above, we are giving the NoteManager a chance to handle the PreviewMouseWheel before doing anything else with it.

    Another point to note is that we have to now "do the scrolling" in code, using the mTextBox.ScrollToVerticalOffset method in the NoteHost class.