Медленное панорамирование и увеличение в WPF

Я нарисовал много строк и текстов на нескольких холстах в WPF. Я использовал самый легкий из возможных элементов в WPF:DrawingVisual

Я нарисовал линии на другом холсте и связал ихthickness с обратным коэффициентом масштабирования, чтобы я мог получить равномерную толщину линии при масштабировании. Это означает, что при масштабировании я перерисовываю холст только линиями. Холст с текстами создается только в начале программы.

Теперь я столкнулся с довольно странной проблемой. Когда я увеличиваю изображение, я получаю медленную производительность. Производительность ухудшается, когда я использую стиль пунктирной линии. Медленно, как при загрузке большого текстового файла в слове, и у вас есть проблемы с прокруткой его!

Моей первой мыслью было, что, возможно, создание линий занимает слишком много времени. Так как я создаю их при каждом увеличении (на колесе мыши), я использовал скромный секундомер, чтобы измерить время, которое требуется между прокруткой колеса мыши до окончания создания линий. К моему удивлению, это займет всего 1 мс! Таким образом, создание линий не может быть проблемой.

С дальнейшим исследованием я понял, что при панорамировании у меня довольно медленная производительность! Медленно, как когда вы пытаетесь панорамировать очень очень большое изображение в окнах!

Так в чем может быть проблема? Я знаю, что вам понадобится некоторый код, но так как код очень длинный, я покажу только то, что происходит внутриMousewheel событие:

private void OnMouseWheel(object sender, MouseWheelEventArgs e)
{
    var sw = new Stopwatch();
    sw.Start();

    var st = GetScaleTransform(Window);
    var tt = GetTranslateTransform(Window);

    var absoluteX = MousePos.Current.X * st.ScaleX + tt.X;
    var absoluteY = MousePos.Current.Y * st.ScaleY + tt.Y;

    const double zoomfactorforwheel = 1.3;
    if (e.Delta > 0)
    {
        st.ScaleX = Math.Min(st.ScaleX * zoomfactorforwheel, Scalemax);
        st.ScaleY = Math.Min(st.ScaleY * zoomfactorforwheel, Scalemax);
    }
    else
    {
        st.ScaleX = Math.Max(st.ScaleX / zoomfactorforwheel, Scalemin);
        st.ScaleY = Math.Max(st.ScaleY / zoomfactorforwheel, Scalemin);
    }
    tt.X = absoluteX - MousePos.Current.X * st.ScaleX;
    tt.Y = absoluteY - MousePos.Current.Y * st.ScaleY;

    Scale = st.ScaleX;

    // Inside this function I'm drawing the lines on drawingvisual
    // Then I'm adding the drawingvisual to a canvas
    DrawZeroWidthDrawing(Scale);

    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);
}

Я начинаю думать, что, возможно, это связано с тем, как все отображается в WPF, или с тем, как обрабатываются кнопки мыши в WPF?Кажется, что-то мешает частоте событий мыши, Любые предложения очень ценятся.

Обновление: я попытался реализовать то, что GameAlchemist сказал в моем коде, к моему удивлению, это все еще медленно.

private MouseWheelEventArgs e;
private bool zoomNeeded;

CompositionTarget.Rendering += CompositionTargetOnRendering;

private void CompositionTargetOnRendering(object sender, EventArgs eventArgs)
{
    if (zoomNeeded)
    {
        zoomNeeded = false;
        DoZoom();

        DrawZeroWidthDrawing();              
    }
}

private void OnMouseWheel(object sender, MouseWheelEventArgs e)
{
    this.e = e;
    zoomNeeded = true;
}

private void DoZoom()
{
    var st = GetScaleTransform(Window);
    var tt = GetTranslateTransform(Window);

    var absoluteX = MousePos.Current.X * st.ScaleX + tt.X;
    var absoluteY = MousePos.Current.Y * st.ScaleY + tt.Y;

    const double zoomfactorforwheel = 1.3;
    if (e.Delta > 0)
    {
        st.ScaleX = Math.Min(st.ScaleX * zoomfactorforwheel, Scalemax);
        st.ScaleY = Math.Min(st.ScaleY * zoomfactorforwheel, Scalemax);
    }
    else
    {
        st.ScaleX = Math.Max(st.ScaleX / zoomfactorforwheel, Scalemin);
        st.ScaleY = Math.Max(st.ScaleY / zoomfactorforwheel, Scalemin);
    }
    tt.X = absoluteX - MousePos.Current.X * st.ScaleX;
    tt.Y = absoluteY - MousePos.Current.Y * st.ScaleY;

    Scale = st.ScaleX;            
}

private static TranslateTransform GetTranslateTransform(UIElement element)
{
    return (TranslateTransform)((TransformGroup)element.RenderTransform)
      .Children.First(tr => tr is TranslateTransform);
}

private static ScaleTransform GetScaleTransform(UIElement element)
{
    return (ScaleTransform)((TransformGroup)element.RenderTransform)
      .Children.First(tr => tr is ScaleTransform);
}

Я понял, возможно, перерисовка линий является виновником, но, похоже, нет! Я удалил вызов функции, которая фактически перерисовывает их с новыми значениями толщины, и оставил только часть масштабирования. Результат не изменился! Мне все еще не хватает производительности.

private void CompositionTargetOnRendering(object sender, EventArgs eventArgs)
{
    if (zoomNeeded)
    {
        zoomNeeded = false;
        DoZoom();
    }
}

Я попытался измерить FPS с помощью инструмента повышения производительности WPF, при масштабировании он падает до 16 ~ 24!

Ответы на вопрос(1)

Ваш ответ на вопрос