2

我目前正在 WPF 中构建波形控件。我打算建立一个缩放功能。这意味着用户应该能够查看整个音频文件的每个样本。众所周知......而且audiofile可以有非常非常非常多的样本。所以我必须画很多线,这将是开销。

所以我考虑只在需要时才画线。问题是我不知道什么是最好和最干净的方法。您对我如何开始构建这样的功能有任何想法吗?我不想要一个看起来像炸脑筋的代码。如果有人有一个好主意来开始解决这个问题,我将非常感激。

4

1 回答 1

0

实现这一目标的一种方法是获取轨道的可见范围,然后绘制属于该区域的线。控件可能对您有所帮助。就个人而言,即使它不使用 WPF 的缩放功能,我也会将样本的坐标保存在只读集合中,然后在需要渲染时将它们的组件乘以缩放因子。您将有一个ScrollViewerwith ScrollableWidth(假设您的样本水平跨越)等于最后一个样本的 x 坐标相乘。获得上述效果的一种方法是始终绘制最后一个样本,而不将其连接到最后一个可见的样本。最后,您将在您选择的容器中绘制可见线并将其用于 ScrollViewer 的Content属性。

Canvas使用 a和 a添加一个小示例ScrollViewer,您可以使用它在滚动/缩放时更新内容。

var scrollViewer = _scrollViewer; //_scrollViewer is our container
var min = scrollViewer.ContentHorizontalOffset; //Calculating visible ranges
var max = min + scrollViewer.ViewportWidth;
int[] samples = { 10, 20, 30, 50, 80, 90, 100, 130 }; //Our original samples
const double zoomFactor = 10.0;
var canvas = new Canvas {HorizontalAlignment = HorizontalAlignment.Left};
foreach (var sampleX in samples)
{
    var multipliedX = sampleX*zoomFactor;
    if (multipliedX < min || multipliedX > max) continue;
    var sampleCircle = new Ellipse {Width = 5, Height = 5, Stroke = Brushes.Black}; //Our Shape for the sample
    canvas.Children.Add(sampleCircle);
    Canvas.SetLeft(sampleCircle, multipliedX);
}
canvas.Width = samples.Last()*zoomFactor; //To extend the ScrollViewer's scrollable width
scrollViewer.Content = canvas;
于 2012-12-16T18:38:00.420 回答