Как сохранить поле изображения (найденное внутри панели) относительно панели при изменении размера панели?
У меня есть приложение 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
Итак, из вашей картины я делаю вывод, что вы хотите как относительного позиционирования, так и относительного изменения размера.
Я уже отвечал на вопрос по этой теме и включил в него набросок с примерами кода о том, как этого достичь. Я найду этот ответ и опубликую его здесь.