Я думаю, что, возможно, нашел обходной путь (читай: грязный трюк) ... этот ответ помог мне правильно указать направление. Вот отрывок из статьи MS, на которую вы также сделали ссылку:
Для вертикальных направлений потока элемент управления FlowLayoutPanel вычисляет ширину подразумеваемого столбца на основе самого широкого дочернего элемента управления в столбце. Все остальные элементы управления в этом столбце со свойствами привязки или закрепления выровнены или растянуты, чтобы соответствовать этому предполагаемому столбцу.
Подобным образом поведение работает для горизонтальных направлений потока. Элемент управления FlowLayoutPanel вычисляет высоту подразумеваемой строки на основе самого высокого дочернего элемента управления в строке, и все закрепленные или закрепленные дочерние элементы управления в этой строке выравниваются или имеют размер, чтобы соответствовать предполагаемой строке.
На этой странице конкретно не упоминается, что вы не можете закрепить / закрепить самый высокий / самый широкий элемент управления. Но поскольку этот элемент управления определяет поведение макета FlowLayoutPanel и, таким образом, влияет на способ отображения всех других элементов управления, родственных друг другу, вполне возможно, что Dock и Anchor не работают должным образом для этого «главного элемента управления». Хотя я не могу найти никакой официальной документации по этому поводу, я считаю, что это так.
Итак, какие у нас есть варианты? Во время выполнения мы могли бы добавить панель управления высотой 0 и шириной клиентской области FlowLayoutPanel до того, как вы добавите свой пользовательский элемент управления. Вы даже можете установить для этой панели значение false. Подписка на некоторые события Resize / Layout FlowLayoutPanel, чтобы сохранить размер этой панели, поможет. Но это не очень хорошо во время разработки. События не срабатывают, и поэтому вы не можете спроектировать поверхность так, как вы хотите, чтобы она выглядела.
Я бы предпочел решение, которое работает и во время разработки. Итак, вот попытка невидимого элемента управления, который я собрал, чтобы исправить изменение размера элементов управления до нулевой ширины, если нет другого элемента управления. Отбрасывание этого элемента в качестве первого элемента управления на FlowLayoutPanel во время разработки, по-видимому, обеспечивает желаемый эффект, и любой элемент управления, впоследствии помещенный в FlowLayoutPanel, может быть закреплен справа без уменьшения ширины до нуля. Единственная проблема заключается в том, что когда этот невидимый элемент управления присутствует, кажется, я больше не могу его удалить через IDE. Вероятно, для этого потребуется особая обработка с использованием ControlDesigner. Однако его все еще можно удалить в коде конструктора формы.
Этот элемент управления, помещенный в FlowLayoutPanel, будет прослушивать события изменения размера своего родительского элемента управления и изменять свой размер в соответствии с ClientSize родительского элемента управления. Используйте с осторожностью, так как это может содержать подводные камни, которые не приходили мне в голову в течение нескольких часов, когда я играл с этим. Например, я не пробовал размещать элементы управления, которые были шире клиентской области FlowLayoutPanel.
В качестве побочного примечания, то, что все равно не удастся, это попытка привязать к основанию, но это не было частью вопроса ;-)
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Windows.Forms;
namespace ControlTest
{
public sealed class InvisibleControl : Control
{
public InvisibleControl()
{
TabStop = false;
}
#region public interface
// Reduce the temptation ...
public new AnchorStyles Anchor
{
get { return base.Anchor; }
set { base.Anchor = AnchorStyles.None; }
}
public new DockStyle Dock
{
get { return base.Dock; }
set { base.Dock = DockStyle.None; }
}
// We don't ever want to move away from (0,0)
public new Point Location
{
get { return base.Location; }
set { base.Location = Point.Empty; }
}
// Horizontal or vertical orientation?
private Orientation _orientation = Orientation.Horizontal;
[DefaultValue(typeof(Orientation), "Horizontal")]
public Orientation Orientation
{
get { return _orientation; }
set
{
if (_orientation == value) return;
_orientation = value;
ChangeSize();
}
}
#endregion
#region overrides of default behaviour
// We don't want any margin around us
protected override Padding DefaultMargin => Padding.Empty;
// Clean up parent references
protected override void Dispose(bool disposing)
{
if (disposing)
SetParent(null);
base.Dispose(disposing);
}
// This seems to be needed for IDE support, as OnParentChanged does not seem
// to fire if the control is dropped onto a surface for the first time
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
ChangeSize();
}
// Make sure we don't inadvertantly paint anything
protected override void OnPaint(PaintEventArgs e) { }
protected override void OnPaintBackground(PaintEventArgs pevent) { }
// If the parent changes, we need to:
// A) Unsubscribe from the previous parent's Resize event, if applicable
// B) Subscribe to the new parent's Resize event
// C) Resize our control according to the new parent dimensions
protected override void OnParentChanged(EventArgs e)
{
base.OnParentChanged(e);
// Perform A+B
SetParent(Parent);
// Perform C
ChangeSize();
}
// We don't really want to be resized, so deal with it
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
ChangeSize();
}
#endregion
#region private stuff
// Make this a default handler signature with optional params, so that this can
// directly subscribe to the parent resize event, but also be called without parameters
private void ChangeSize(object sender = null, EventArgs e = null)
{
Rectangle client = Parent?.ClientRectangle ?? new Rectangle(0, 0, 10, 10);
Size proposedSize = _orientation == Orientation.Horizontal
? new Size(client.Width, 0)
: new Size(0, client.Height);
if (!Size.Equals(proposedSize)) Size = proposedSize;
}
// Handles reparenting
private Control boundParent;
private void SetParent(Control parent)
{
if (boundParent != null)
boundParent.Resize -= ChangeSize;
boundParent = parent;
if (boundParent != null)
boundParent.Resize += ChangeSize;
}
#endregion
}
}
person
takrl
schedule
28.04.2016
UserControl
каким-то образом становится0,0
, когда дляDock
установлено значениеDockStyle.Fill
. Я думаю, это может быть из-за того, чтоUserControl
не имеет собственного размера. Я сам здесь очень запутался. - person binki   schedule 12.06.2014UserControl
. Это также происходит, если вы используете стандартный элемент управления Panel, и поведение по-прежнему сохраняется с .net461 в VS2015. - person takrl   schedule 28.04.2016