Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过设置输入点和输出点在WPF中动态缩放画布_C#_Wpf - Fatal编程技术网

C# 通过设置输入点和输出点在WPF中动态缩放画布

C# 通过设置输入点和输出点在WPF中动态缩放画布,c#,wpf,C#,Wpf,我正在使用canvas元素在WPF中绘制程序。我想要实现的是一个带有可拖动端点的滚动条。Adobe的After Effects视频编辑软件中提供了此类滚动条的示例 这种滚动条的基本功能是,它能够滚动比其容器大的内容,但可以拖动左右端点来动态更改内容的比例 我在绘图程序中实现了类似的滚动条;用户应该能够在输入和输出点(画布中的矩形)周围拖动,绘图画布应该通过缩放到所需的范围来响应这一点。 我需要这方面的信息: 总绘图的宽度(绘图点的数量) 容器宽度(静态,600px) 输入和输出点相对于滚动条画

我正在使用canvas元素在WPF中绘制程序。我想要实现的是一个带有可拖动端点的滚动条。Adobe的After Effects视频编辑软件中提供了此类滚动条的示例

这种滚动条的基本功能是,它能够滚动比其容器大的内容,但可以拖动左右端点来动态更改内容的比例

我在绘图程序中实现了类似的滚动条;用户应该能够在输入和输出点(画布中的矩形)周围拖动,绘图画布应该通过缩放到所需的范围来响应这一点。 我需要这方面的信息:

  • 总绘图的宽度(绘图点的数量)
  • 容器宽度(静态,600px)
  • 输入和输出点相对于滚动条画布总宽度的百分比

根据这些信息,我创建了一个MatrixTransform,使用ScaleAt()方法缩放容器内的绘图画布,使其与下面滚动条中的输入点和输出点匹配。为此,我使用了以下代码。resetTransform每秒调用FPS次以跟上传入数据,XMAX和YMAX在别处更新以反映这一点。

期望值:当绘图点的数量随时间增长时,一切都应该正常工作,并且绘制的图形可以很好地缩放。现实情况:当移动点时,图形会缩放,但不具有代表性;此外,添加的绘图点越多,整个画布越向右移动,我对转换的控制似乎越少。现在的算法可能是错误的,无法得到我所需要的结果,但我花了相当长的时间思考如何正确地做到这一点

更新

我上传了一段视频,以便更清楚地了解互动情况。在视频中,您可以清楚地看到画布向右移动。


我应该如何缩放画布(绘图)以适应两个边界

所以,经过一番努力,我找到了解决这个问题的正确算法。我将在下面发布resetTransform函数的调整版本:

    //Reset graph transform
    public void resetTransform(Boolean useSlider = false)
    {
        double yscale = plot.Height / view.YMAX; //YMAX is maximum plot value received
        double xscale = plot.Width / view.XMAX; //XMAX is total ammount of plotted points
        Matrix m = new Matrix(1, 0, 0, 1, 0, 0);
        if (useSlider)
        {
            double maxVal = zoomBar.ActualWidth - outPoint.Width;
            double outP = Canvas.GetLeft(outPoint); //points position relative to the scrollbar
            double inP = Canvas.GetLeft(inPoint);
            double delta = (outP-inP);
            double factor = (maxVal/delta) * xscale;

            anchorOut = (outP / maxVal) * view.XMAX; //Define anchorpoint coordinates
            anchorIn = (inP / maxVal) * view.XMAX;
            double center = (anchorOut +anchorIn)/2; //Define centerpoint

            m.Translate(-anchorIn, 0); //Move graph to inpoint
            m.ScaleAt(factor, -yscale,0,0); //scale around the inpoint, with a factor so that outpoint is plot.Height(=600px) further away
            m.Translate(0, plot.Height); //to compensate the flipped graph, move it back down
        }
            scale = new ScaleTransform(m.M11, m.M22, 0, 0); //save scale factors in a scaletransform for reference
            signals.scaleSignalStrokes(scale); //Scale the plotlines to compensate for canvas scaling
            MatrixTransform matrixTrans = new MatrixTransform(m); //Create matrixtransform
            plot.RenderTransform = matrixTrans; //Apply to canvas
    }
因此,与其围绕中心点进行缩放,我应该首先平移图像,然后使用因子围绕画布的原点进行缩放。这意味着画布的另一面正好是plot.Height像素(添加了一些缩放)

现在一切似乎都很好,但因为我使用自定义控件(画布中的可拖动矩形),我注意到这些矩形并不总是触发mouse事件


因为它超出了这个问题的范围,我在

中进一步描述了这个问题,所以经过一些努力,我找到了解决这个问题的正确算法。我将在下面发布resetTransform函数的调整版本:

    //Reset graph transform
    public void resetTransform(Boolean useSlider = false)
    {
        double yscale = plot.Height / view.YMAX; //YMAX is maximum plot value received
        double xscale = plot.Width / view.XMAX; //XMAX is total ammount of plotted points
        Matrix m = new Matrix(1, 0, 0, 1, 0, 0);
        if (useSlider)
        {
            double maxVal = zoomBar.ActualWidth - outPoint.Width;
            double outP = Canvas.GetLeft(outPoint); //points position relative to the scrollbar
            double inP = Canvas.GetLeft(inPoint);
            double delta = (outP-inP);
            double factor = (maxVal/delta) * xscale;

            anchorOut = (outP / maxVal) * view.XMAX; //Define anchorpoint coordinates
            anchorIn = (inP / maxVal) * view.XMAX;
            double center = (anchorOut +anchorIn)/2; //Define centerpoint

            m.Translate(-anchorIn, 0); //Move graph to inpoint
            m.ScaleAt(factor, -yscale,0,0); //scale around the inpoint, with a factor so that outpoint is plot.Height(=600px) further away
            m.Translate(0, plot.Height); //to compensate the flipped graph, move it back down
        }
            scale = new ScaleTransform(m.M11, m.M22, 0, 0); //save scale factors in a scaletransform for reference
            signals.scaleSignalStrokes(scale); //Scale the plotlines to compensate for canvas scaling
            MatrixTransform matrixTrans = new MatrixTransform(m); //Create matrixtransform
            plot.RenderTransform = matrixTrans; //Apply to canvas
    }
因此,与其围绕中心点进行缩放,我应该首先平移图像,然后使用因子围绕画布的原点进行缩放。这意味着画布的另一面正好是plot.Height像素(添加了一些缩放)

现在一切似乎都很好,但因为我使用自定义控件(画布中的可拖动矩形),我注意到这些矩形并不总是触发mouse事件


因为它不在这个问题的范围之内,我已经在

中进一步描述了这个问题,可以使用第三方控制吗?telerik RadTimeBar和RadTimeLine有这种行为。啊,我明白了,这些控件正是我需要的,但它们是商业工具。我希望自己编写解决方案,从错误中吸取教训,并将项目放在github上,因此上述工具在这方面并没有真正帮助我。除非他们在网站上的某个地方向我展示底层代码,否则可以使用第三方控制吗?telerik RadTimeBar和RadTimeLine有这种行为。啊,我明白了,这些控件正是我需要的,但它们是商业工具。我希望自己编写解决方案,从错误中吸取教训,并将项目放在github上,因此上述工具在这方面并没有真正帮助我。除非他们在网站上的某个地方向我展示底层代码?