Добавление текстового поля в табличную панель выводит текстовое поле в "случайные" места
У меня есть простое приложение winform, которое позволяет пользователям перетаскивать элементы управления на панель таблиц. Но после некоторого тестирования и попытки перетащить элементы управления в определенную строку индекса, я обнаружил, что это не работает, даже с индексом с жестким кодом.
В приведенном примере кода я пытаюсь добавить текстовое поле в индекс строки 2, но когда я перетаскиваю содержимое из списка в панель таблицы, он просто добавляет текстовое поле в "случайных" местах, как показано на скриншоте ниже.
Я ожидаю, что существующие текстовые поля сместятся вниз и освободят место для добавляемого текстового поля, насколько я понимаю из этого: https://social.msdn.microsoft.com/Forums/windows/en-US/e4312cd8-6031-4a5c-92bf-e8adb1941fe5/insert-row-at-particular-position-in-table-layout-panel?forum=winforms.
Я делаю что-то неправильно?
Код дизайнера:
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.listBox1 = new System.Windows.Forms.ListBox();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.SuspendLayout();
//
// listBox1
//
this.listBox1.FormattingEnabled = true;
this.listBox1.Location = new System.Drawing.Point(367, 12);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(190, 407);
this.listBox1.TabIndex = 0;
this.listBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDown);
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Location = new System.Drawing.Point(13, 12);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 1;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(332, 407);
this.tableLayoutPanel1.TabIndex = 1;
this.tableLayoutPanel1.DragDrop += new System.Windows.Forms.DragEventHandler(this.tableLayoutPanel1_DragDrop);
this.tableLayoutPanel1.DragEnter += new System.Windows.Forms.DragEventHandler(this.tableLayoutPanel1_DragEnter);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(569, 431);
this.Controls.Add(this.tableLayoutPanel1);
this.Controls.Add(this.listBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
}
Код формы:
public partial class Form1 : Form
{
private int tempInt = 0;
public Form1()
{
InitializeComponent();
listBox1.Items.AddRange(new object[] { "test" });
tableLayoutPanel1.AllowDrop = true;
tableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
tableLayoutPanel1.AutoScroll = true;
tableLayoutPanel1.RowCount = 3;
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
tempInt++;
DoDragDrop("test" + tempInt, DragDropEffects.Copy);
}
private void tableLayoutPanel1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void tableLayoutPanel1_DragDrop(object sender, DragEventArgs e)
{
string text = e.Data.GetData(typeof(String)) as string;
TextBox tb = new TextBox();
tb.Dock = DockStyle.Fill;
tb.Text = text;
// I want to add the textbox to the second row
tableLayoutPanel1.Controls.Add(tb, 0, 2);
tableLayoutPanel1.SetRow(tb, 2);
}
}
РЕДАКТИРОВАТЬ:
Добавлен код, основанный на предложенном ДонБойноттом
private void tableLayoutPanel1_DragDrop(object sender, DragEventArgs e)
{
string text = e.Data.GetData(typeof(String)) as string;
TextBox tb = new TextBox();
tb.Dock = DockStyle.Fill;
tb.Text = text;
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
for (int i = 0; i < tableLayoutPanel1.Controls.Count; i++)
{
int pos = tableLayoutPanel1.GetRow(tableLayoutPanel1.Controls[i]);
if (pos > 1)
{
tableLayoutPanel1.SetRow(tableLayoutPanel1.Controls[i], pos + 1);
}
}
tableLayoutPanel1.Controls.Add(tb, 0, 2);
}
1 ответ
Попробуйте этот измененный класс формы, я внес несколько изменений:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listBox1.Items.AddRange(new Object[] { "TextBox" });
tableLayoutPanel1.AllowDrop = true;
tableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
tableLayoutPanel1.AutoScroll = true;
tableLayoutPanel1.RowStyles.Clear();
tableLayoutPanel1.ColumnStyles.Clear();
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
}
private void listBox1_MouseDown(Object sender, MouseEventArgs e)
{
var count = tableLayoutPanel1.Controls.Count;
DoDragDrop($"test{count + 1}", DragDropEffects.Copy);
}
private void tableLayoutPanel1_DragEnter(Object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void tableLayoutPanel1_DragDrop(Object sender, DragEventArgs e)
{
var tb = new TextBox();
tb.Dock = DockStyle.Fill;
tb.Text = (e.Data.GetData(typeof(String)) as String);
var newRow = tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
var ctrl = tableLayoutPanel1.GetChildAtPoint(tableLayoutPanel1.PointToClient(new Point(e.X, e.Y)));
if (ctrl != null)
{
var pos = tableLayoutPanel1.GetRow(ctrl);
for (Int32 i = tableLayoutPanel1.RowStyles.Count - 2; i >= pos; i--)
{
var c = tableLayoutPanel1.GetControlFromPosition(0, i);
if (c != null)
tableLayoutPanel1.SetRow(c, i + 1);
}
tableLayoutPanel1.Controls.Add(tb, 0, pos);
}
else
tableLayoutPanel1.Controls.Add(tb, 0, newRow);
}
}
Основные шаги:
- Я выпал на существующий контроль? Если так, определите, где.
- Если это так, работайте снизу вверх, перемещая каждый элемент управления вниз по слоту. Вы должны избегать дублирования, два элемента управления не могут занимать одну и ту же ячейку.
- Если это так, вставьте новый элемент управления в недавно освобожденный слот в точке сброса.
- Если нет, просто добавьте элемент управления в конце.