Member 10334528 Ответов: 2

Как сохранить поле изображения (найденное внутри панели) относительно панели при изменении размера панели?


У меня есть приложение windows forms с прямоугольной панелью в центре. Эта панель имеет фоновое изображение, которое важно для графических блоков (с фоновыми изображениями), которые затем тщательно располагаются над верхней частью панели. Я установил панель на якорь сверху, снизу, слева и справа с фоновым изображением макета масштабирования. Это позволяет изменять размер изображения панели при изменении размера окна. Отлично!

Проблема, с которой я столкнулся, заключается в том, что мне нужно, чтобы графические поля оставались в одном и том же положении относительно фонового изображения панели позади него. В настоящее время, когда окно форм изменяется, изображения сверху перемещаются из положения относительно панели позади него, которая изменяется правильно. Они движутся так, как будто у них есть правый нижний якорь, но их якорь не установлен ни на один.

Другими словами, если я расположил изображение на 30% поперек панели, мне нужно, чтобы оно было на 30% поперек панели, даже если размер панели изменился.

Изображение ниже показывает именно то, что мне нужно:

http://i261.photobucket.com/albums/ii61/scottj15_2008/PanelResize_zpsfea30619.png

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

большое спасибо

Фактический код для решения (спасибо BillWoodruff):

Это решение базируется на хранение коэффициент для каждого элемента управления PictureBox по отношению к панели, а затем использовать это соотношение в методе Form_SizeChanged, чтобы изменить размер &ампер; повторно Poistion каждого элемента управления PictureBox.

Важно: это решение основано на том, что панель уже автоматически изменяет свой размер с помощью всех 4 анкеров.

Во-первых, нам нужны словари, чтобы удерживать соотношение положения и размера для каждой коробки с картинками:
//Location Ratios
private Dictionary<Control, double> XRatio = new Dictionary<Control, double>();
private Dictionary<Control, double> YRatio = new Dictionary<Control, double>();
//Size Ratios
private Dictionary<Control, double> XSizeRatio = new Dictionary<Control, double>();
private Dictionary<Control, double> YSizeRatio = new Dictionary<Control, double>();


В случае загрузки нам нужно сохранить соотношение для каждого picturebox:
foreach (Control thisControl in panel.Controls)
{
    if (thisControl is PictureBox)
    {
        //Location Ratios
        XRatio.Add(theControl, Convert.ToDouble(thisControl.Left) / panel.Width);
        YRatio.Add(theControl, Convert.ToDouble(thisControl.Top) / panel.Height);
        //Size Ratios
        XSizeRatio.Add(theControl, Convert.ToDouble(thisControl.Width) / panel.Width);
        YSizeRatio.Add(theControl, Convert.ToDouble(thisControl.Height) / panel.Height);
    }
}


Затем нам нужно использовать это соотношение для изменения размера / положения каждого PictureBox всякий раз, когда изменяется размер окна формы:
private void Form_SizeChanged(object sender, EventArgs e)
{
    foreach (Control thisControl in panel.Controls)
    {
        if (thisControl is PictureBox)
        {
            //*********************Re-Position the PictureBox********************
            double localXRatio = 0;
            double localYRatio = 0;
            //Grab the Location Ratios for this particular PictureBox
            localXRatio = XRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
            localYRatio = YRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
            //Calculate the new Location by using the ratios
            newX = Convert.ToInt32(panel.Width * localXRatio);
            newY = Convert.ToInt32(panel.Height * localYRatio);
            //Set the new Location
            thisControl.Location = new Point(newX, newY);
            //*********************Re-Size the PictureBox********************
            double localXSizeRatio = 0;
            double localYSizeRatio = 0;
            //Grab the Size Ratios for this particular PictureBox
            localXSizeRatio = XSizeRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
            localYSizeRatio = YSizeRatio.FirstOrDefault(ratio => ratio.Key == thisControl).Value;
            //Calculate the new sizes by using the set ratio
            newWidth = Convert.ToInt32(panel.Width * localXSizeRatio);
            newHeight = Convert.ToInt32(panel.Height * localYSizeRatio);
            //Set the new Size
            thisControl.Width = newWidth;
            thisControl.Height = newHeight;
        }
    }
}

CHill60

Это прекрасно работает для меня, когда я пытаюсь это сделать ... вы сказали: "осторожно располагайтесь над верхней частью панели"... для работы якоря коробки с картинками должны быть внутри панель-это ваша проблема?

Member 10334528

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

CHill60

Попробовать стоило :-) Спасибо за подтверждение. Я попробую еще раз попытаться воссоздать вашу проблему

CHill60

Просто мысль - вы стыковываете изображение со всеми 4-мя верхними, нижними, левыми и правыми? И это изображение коробки с картинками или фоновое изображение, которое вы используете?

Member 10334528

В настоящее время ничего не закреплено, но панель имеет все 4 верхних, нижних, левых, правых якоря вместе с BackgroundImageLayout = Zoom, так что она изменяется при любом изменении размера окна.

Графические окна используют фоновое изображение и не имеют якоря, но они, похоже, ведут себя так, как если бы были выбраны правый и Нижний якоря.

Vic91

Я согласен, но я думаю, что он должен установить якорь для pictureboxes сверху, снизу, слева и справа вместо none? Если панель закреплена, то и pictureboxes должны быть такими же.

Member 10334528

Я уже пробовал. PictureBoxes остаются полностью неподвижными, в то время как фоновое изображение панели перемещается за ним, когда это установлено.

BillWoodruff

Являются ли четыре PictureBoxes единственными элементами управления на панели ?

Вы хотите, чтобы PictureBoxes меняли размер пропорционально размеру панели, или вы хотите, чтобы стороны PictureBoxes поддерживали постоянное расстояние от сторон панели без изменения размера ?

TnTinMn

"если я расположил изображение на 30% поперек панели, мне нужно, чтобы оно было на 30% поперек панели, даже если панель изменилась. "

Возможно, я слишком упрощаю это, но почему бы не установить расположение picturebox в обработчике событий Panel. Resize равным 30% ширины панели?

BillWoodruff

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

Member 10334528

Спасибо вам обоим за ответы. Билл Вудрафф, я отвечу на оба ваших вопроса здесь, чтобы все было просто.

Есть более 65 PictureBoxes, размещенных на верхней части этой панели, а не только 4, Но да, они являются единственными элементами управления на панели.
Я хочу, чтобы графические поля оставались в том же положении/размере относительно фона панели позади него, что и в режиме конструктора. Пожалуйста, перейдите по ссылке ниже, где я загрузил фотографию, которая, надеюсь, сделает ее более понятной.

http://i261.photobucket.com/albums/ii61/scottj15_2008/PanelResize_zpsfea30619.png

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

BillWoodruff

Итак, из вашей картины я делаю вывод, что вы хотите как относительного позиционирования, так и относительного изменения размера.

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

2 Ответов

Рейтинг:
13

BillWoodruff

Вот обзор того, как добиться относительного позиционирования и изменения размера элементов управления при изменении размера формы элементов управления / ContainerControl [^].

Мне пока не удалось получить разрешение на публикацию всего кода на CP, но я надеюсь на это.

Я предлагаю вам прочитать различные комментарии к этому посту и другие ответы. Я также предлагаю вам избегать попыток масштабировать размер шрифта в элементах управления с помощью текста: это обычно приводит к типографскому беспорядку в WinForms.


Member 10334528

Большое спасибо! Я играл в течение последних 2-3 часов с материалом, который вы предоставили,и я успешно получил все PictureBoxes для изменения размера и перемещения с помощью изменения размера formwindow.

Я принял ваше решение и обновил вопрос с помощью кода, который я использовал, чтобы помочь кому-либо в будущем.

Большое Спасибо!! :)

Рейтинг:
1

AhmedMSedeek

Я думаю, что вы сами упомянули об этом решении,

Если я правильно понял проблему, вам нужно использовать соотношение, как вы сказали.

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