2016-09-01 5 views
0

Как мне это нужно:C# Windows Forms Как сохранить местоположение и размер управления относительно постоянным в его родительском контейнере?

left to right

Dock:

Я не хочу, чтобы прикрепить ее к какой-либо из сторон в принципе.

Anchor для всех сторон:

keeps the corner location constant

Anchor Нет:

Он делает сохраняет расположение относительно постоянной, но не изменять их вообще.

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

Пожалуйста, покажите мне более чистый способ, спасибо.

Edit: у меня будет несколько элементов управления, плавающие в этом контейнере. Таким образом, TableLayoutView не является вариантом для этого случая.

Кроме того, в ответ от sam он предлагает вручную выполнить эту работу, как я боялся. Ну, я думаю, мне придется это делать так.

Копирование вручную с помощью элементов управления детьми на событие управления контейнером Resize.

Я помечаю это как решение, хотя я не удовлетворен.

+0

это выглядит как масштабирование, работа в 'ViewBox' в WPF, но я не думаю, что это будет е asy в winforms. Ручное изменение размера является одним из возможных: подписаться на контейнер ['SizeChanged'] (https://msdn.microsoft.com/en-us/library/system.windows.forms.control.sizechanged (v = vs.110) .aspx) события и перемещение детей. Или попробуйте использовать «TableLayoutPanel» с относительными единицами для столбцов и строк. – Sinatr

ответ

0

Конечный результат:

Resizing done.

У меня есть этот класс, который содержит ссылки на контейнера и его детей. Заграничный DynoPanel здесь содержит контроль внутри.

private readonly Dictionary<string, DynoPanel> children; 
public Panel container; 
private List<Rectangle> startingRectangles; 

public DynoContainer(Control parent) 
{ 
    children = new Dictionary<string, DynoPanel>(); 
    container = new Panel 
    { 
     Dock = DockStyle.Fill 
    }; 
    parent.Controls.Add(container); 
    container.FindForm().ResizeBegin += OnResizeBegin; 
    container.Resize += ContainerOnResize; 
} 

Здесь мы храним Начало местоположения и размеров контейнера и его детей на ResizeBegin случае материнской формы:

private void OnResizeBegin(object sender, EventArgs eventArgs) 
{ 
    startingRectangles = new List<Rectangle>(); 
    startingRectangles.Add(container.Bounds); 
    foreach (var dynoPanel in children) 
     startingRectangles.Add(dynoPanel.Value.self.Bounds); 
} 

Тогда в соответствии с новым коэффициентом масштабирования мы рассчитали, детские места и размеры установлены, сохранение первоначального соотношения на фактическое Resize событие:

private void ContainerOnResize(object sender, EventArgs eventArgs) 
{ 
    var scale = new PointF(
     (float) container.Width/startingRectangles[0].Width, 
     (float) container.Height/startingRectangles[0].Height); 
    int index = 1; 
    foreach (var panel in children) 
    { 
     panel.Value.self.Location = new Point(
      (int) (startingRectangles[index].X*scale.X), 
      (int) (startingRectangles[index].Y*scale.Y) 
      ); 
     panel.Value.self.Size = new Size(
      (int) (startingRectangles[index].Width*scale.X), 
      (int) (startingRectangles[index].Height*scale.Y) 
      ); 
     index++; 
    } 
} 
0

Предположим, что ваш внутренний элемент всегда удален от левой границы 1% от общей ширины окна. Вы можете рассчитать свое фактическое значение после инициализации своей формы.

при изменении размера (есть событие) пересчитывать бетонную левое положение путем вычисления нового расстояния и присвоение ему Left = form.Width*0.01