winforms 如何使自定义滚动条与图表中的可见内容成比例?

1cosmwyk  于 2023-03-03  发布在  其他
关注(0)|答案(1)|浏览(166)

问题陈述

我一直在使用一个自定义网格控件,其视口大小正好为1024****像素,用于绘制信号点。请注意,一个完整的信号也正好由1024个点组成。这意味着一个信号扩展到网格的整个宽度。
我还可以放大图形,增加信号点乘以缩放因子,即:

...
const int SignalLength = 1024;
int ZoomFactor = 2;    //Updated by user
int NewPoints = SignalLength * ZoomFactor;
...

我一直在尝试创建自定义的滚动条,以帮助滚动缩放的信号。然而,我一直面临的问题,在保持滚动和同步的可见内容的比例。

视觉示例[缩放系数:2]

我研究过的几个参数是:

      • 滚动按钮**:每个尺寸50x50像素
      • 可滚动区域**:由于滚动按钮的作用而减少,即Grid Width - (50*2):* * 924**像素。
      • 洗涤器宽度**:始终为Scrollable Area / ZoomFactor

请注意图中的箭头,它显示了信号的可见部分并不与擦洗器同步。我猜擦洗器移动得太快了,比网格实际显示的要快。
编号

private void ZoomFactor_Changed(object sender, EventArgs e)
{
    if (ZoomFactor > 1)
    {
        Scrubber.Width = (ScrubberTrackPanel.Width / ZoomFactor);
        ScrubberWidth.Text = Scrubber.Width.ToString();
        ScrubberTrackPanel.Visible = true;
    }
    else
    {
        ScrubberTrackPanel.Visible = false;
        Scrubber.Width = Scrubber.Parent.Width;
    }
}

private void SfBtn_GridScrollRight_MouseDown(object sender, MouseEventArgs e)
{
   // Both left and right button's tag property have the step value.
   // Left has -2 
   // Right has 2
   GlobalVars.GridScrubStepSize = 0 + int.Parse((SfButton)sender).Tag.ToString());
   GridScrubberTimer.Start();
}

private void GridScrubberTimer_Tick(object sender, EventArgs e)
{
    ScrollGrid(GlobalVars.GridScrubStepSize);
}

private void ScrollGrid(int StepSize)
{
   var newStepPos = GlobalVars.ZoomedSignalLeft + StepSize;
   //To stop scroll timer if any of the boundry (left/right) of graph is reached.
   if (newStepPos <= 0 || newStepPos >= 1024 * ZoomFactor && GridScrubberTimer.Enabled)
   {
       GridScrubberTimer.Stop();
       return;
   }
   var ZoomedSignalSlice = GlobalVars.ZoomedSignal.Skip(newStepPos).Take(1024).ToList();
   if (ZoomedSignalSlice.Count == 1024)
   {
       GlobalVars.ZoomedSignalLeft += GlobalVars.GridScrubStepSize;
       if (ScrubberTrackPanel.Visible)
       {
           Scrubber.Location = new Point(Scrubber.Location.X + (int)Math.Floor(GlobalVars.GridScrubStepSize/ (float)ZoomFactor), 0);
           ScrubberCords.Text = Scrubber.Location.ToString();
       }
       GraphGrid.Refresh();
   }
}

尝试的解决方案

我试过How to calculate the size of scroll bar thumbFormula for content step of scrollbar,但不知何故,我无法正确掌握比例。
我肯定我错过了一些非常明显的(&& stupid:p)东西,你会解释清楚的。

v2g6jxz6

v2g6jxz61#

在对代码修修补补了几个小时后,我意识到位置的计算非常错误。修复后,滚动正如预期的那样工作,同时保持适当的比例。
下面是正确的代码:

...
GlobalVars.ZoomedSignalLeft += GlobalVars.GridScrollStepSize;
// Mapping the current beginning position of the visible signal on the grid in the range of ScrollerTrackPanel and then dividing 
// it with the ZoomFactor To get location of scrubber over the signal image proportional to the visible signal on the grid.
int newx = (int)Math.Floor(GlobalVars.ZoomedSignalLeft / 1024F * ScrollerTrackPanel.Width / ZoomFactor);
Scrubber.Location = new Point(newx, 0);
...

相关问题