Устранение ошибок округления при изменении размеров элементов управления на Winform - PullRequest
0 голосов
/ 06 февраля 2010

У меня есть требование изменить размеры всех элементов управления в форме при изменении размера моей формы. К сожалению, из-за некоторых проблем я не могу использовать какой-либо контейнерный элемент управления или использовать свойство anchor / dock. Мне нужно сделать все, используя код. Я могу изменить размеры элементов управления в соответствии с соотношением размеров экрана. При выполнении этого изменения размера мне нужно вычислить новую позицию всех элементов управления вместе с новым размером. Проблема заключается в том, что при вычислении этих новых точек я получаю новые значения в десятичном формате, и если я их округляю, то это вызывает проблемы и вычисляет неправильный размер и положение каждый раз, когда я изменяю размер своей формы. Я видел несколько сторонних элементов управления для той же задачи, но все они точно рассчитывают позицию.

Пожалуйста, помогите мне решить эту проблему. Заранее спасибо, Ашиш Шарма

1 Ответ

0 голосов
/ 06 февраля 2010

Это C # / Windows Forms?

Ручное масштабирование - это боль в шее. Реально, единственный способ полностью предотвратить любые серьезные ошибки округления в течение длительного срока жизни формы - это сохранить исходные местоположения и размеры каждого элемента управления, который вы перемещаете / изменяете размер, и делать весь ваш код перемещения / изменения размера относительно исходной позиции в отличие от текущей позиции.

В итоге у вас возникнет какая-то глупость:

public class Form1
{
    private Size originalFormSize;

    private List<Control> controlsToResize = new List<Control>();
    private List<Point> originalLocations;
    private List<Size> originalSizes;

    public Form1()
    {
        InitializeComponent();
        SaveOriginalSizes();
    }

    private void SaveOriginalSizes()
    {
        originalFormSize = Size;
        controlsToResize.Add(panel1);
        controlsToResize.Add(panel2);
        ...
        originalLocations = new List<Point>(controlsToResize.Count);
        originalSizes = new List<Size>(controlsToResize.Count);
        foreach (Control c in controlsToResize)
        {
            originalLocations.Add(c.Location);
            originalSizes.Add(c.Size);
        }
    }

    protected override void OnResize(EventArgs e)
    {
        base.OnResize(e);
        float scaleX = (float)originalFormSize.Width / Size.Width;
        float scaleY = (float)originalFormSize.Height / Size.Height;
        for (int i = 0; i < controlsToResize.Count; i++)
        {
            Control c = controlsToResize[i];
            UpdatePosition(c, originalLocations[i], scaleX, scaleY);
            UpdateSize(c, originalSizes[i], scaleX, scaleY);
        }
    }
}

... Там, где вам, очевидно, придется реализовать методы UpdatePosition и UpdateSize самостоятельно - я предполагаю, что у вас уже есть какая-то реализация.

Честно говоря, это ужасно ужасно. Я бы настоятельно рекомендовал бы вместо того, чтобы пытаться сделать что-либо из этого, вы пересмотрите все требования / конструктивные ограничения, которые мешают вам использовать свойства Anchor и Dock. Во всех мои годы, я не думаю, что когда-либо слышал о законной причине не использовать ни эти, ни элементы управления макетом TableLayoutPanel / FlowLayoutPanel, ни оба. Это способ иметь дело с макетами в WinForms; все остальное - неуклюжий взлом.

...