Как я могу предотвратить мерцание моих растровых изображений, когда я отпускаю их от перетаскивания? - PullRequest
0 голосов
/ 07 июня 2019

Я создаю свое собственное приложение в Winforms, где я хочу иметь возможность создавать карту и наносить на нее значки.Эти значки будут отображать информацию при нажатии.Карта представляет собой простое изображение, а значки - растровые изображения.Пользователь может перетащить значок на карту, а затем снова перетащить его или удалить.

Проблема заключается в том, что когда я перетаскиваю значок (растровое изображение) и отпускаю его, он на мгновение мигает.Это будет происходить независимо от скорости, и независимо от того, будет ли это самое первое размещение иконки.

Мой репозиторий для кода: https://github.com/Foxion7/MapMarker

Скриншот панелей, иконоки т. д .: https://imgur.com/a/pKMJ4lX Справа находится значок, который можно щелкнуть, чтобы перетащить новый значок на карту.

Я уже пробовал использовать изображения с прозрачностью (не работал для проблем, не связанных с мерцанием), двойная буферизация, проверка чрезмерного использования Invalidate ().

Я также был бы признателен за советы по другим способам, кроме растровых изображений и нескольких панелей, чтобы, возможно, обойти проблему, но я до сих пор довольно далеко с этим справился.

Ниже приведена выдержка для перемещения значка в панели.

    // Selecting an existing icon. 
    private void mapPictureBox_MouseDown(object sender, MouseEventArgs e)
    {
        Icon selectedIcon = map.CheckCollision(e.Location);
        if (selectedIcon != null)
        {
            SelectIcon(selectedIcon);
            currentOffset = new Point((e.X - selectedIcon.center.X) * -1, (e.Y - selectedIcon.center.Y) * -1);
            holdingAnIcon = true;
        }
    }

    // Only hides icon on old position when you start dragging to prevent flashing.
    private void mapPictureBox_MouseMove(object sender, MouseEventArgs e)
    {
        if (holdingAnIcon)
        {
            if(oneTimePerMoveActionsDone)
            {
                selectedIcon.hidden = true;
                mapPictureBox.Invalidate();
                oneTimePerMoveActionsDone = false;
            }
            var dragImage = ResizeImage(selectedIcon.bitmap, iconWidth, iconHeight);
            IntPtr icon = dragImage.GetHicon();
            Cursor.Current = new Cursor(icon);
        }
    }

    // Releasing after dragging an existing icon.
    private void mapPictureBox_MouseUp(object sender, MouseEventArgs e)
    {
        if (holdingAnIcon)
        {
            selectedIcon.location = mapPanel.PointToClient(new Point(e.X - (int)(iconWidth / 3.75) + currentOffset.X, e.Y + iconHeight / 5 + currentOffset.Y));
            selectedIcon.UpdateCenterPosition();
            selectedIcon.hidden = false;
            holdingAnIcon = false;
            oneTimePerMoveActionsDone = true;

            mapPictureBox.Invalidate();
        }
    }

Мерцание (почти всегда) происходит при отпускании кнопки мыши.Существует лишь очень малая вероятность того, что мерцание иногда не появляется.

...