Настройка столбцов ListView в соответствии с WinForms
Я столкнулся с проблемой изменения размера столбцов listview. Если вы привязываете / закрепляете listview к обычной winform, то якорь или закрепление listview работает хорошо. Я имею в виду, что listview будет изменять размер и соответствовать winforms, как winforms максимизируется, но столбцы, которые вы разработали на нем, которые не изменяют размер с помощью listview.
Мой вопрос: есть ли способ изменить размер столбцов listview с помощью listview, чтобы они соответствовали размеру winform?.
Код Проекта Listview:
private void Form1_Load(object sender, EventArgs e)
{
listView1.View = View.Details;
listView1.LabelEdit = true;
listView1.BackColor = Color.GreenYellow;
listView1.Columns.Add("Date", 100, HorizontalAlignment.Left);
listView1.Columns.Add("TransID", 50, HorizontalAlignment.Left);
listView1.Columns.Add("voucher", 100, HorizontalAlignment.Right);
listView1.Columns.Add("particulars", 300, HorizontalAlignment.Left);
listView1.Columns.Add("deposit", 100, HorizontalAlignment.Right);
listView1.Columns.Add("withdrawal", 100, HorizontalAlignment.Right);
string connstr = "server=.;initial catalog=DataBase;uid=UID;pwd=PWD";
SqlConnection con = new SqlConnection(connstr);
con.Open();
listView1.Items.Clear();
listView1.Refresh();
string sql = "select date=convert(varchar,date,103),transID,max(particulars)as particulars,sum(deposit)as deposit,sum(withdrawal) as withdrawal,voucher from debank group by date,transID,voucher";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataAdapter dap = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
dap.Fill(ds);
DataTable dt = ds.Tables[0];
for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow dr = dt.Rows[i];
ListViewItem lvi = new ListViewItem(dr["date"].ToString());
lvi.SubItems.Add(dr["transID"].ToString());
lvi.SubItems.Add(dr["voucher"].ToString());
lvi.SubItems.Add(dr["particulars"].ToString());
lvi.SubItems.Add(dr["deposit"].ToString());
lvi.SubItems.Add(dr["withdrawal"].ToString());
listView1.Items.Add(lvi);
listView1.FullRowSelect = true;
}
SizeLastColumn(listView1);
}
5 ответов:
- программная единица. Вам придется поддерживать его в коде.
- Вы можете настроить размер последнего столбца в listview таким образом, чтобы он автоматически изменялся. Чистый образец:
В элементе управления ListView, с видом свойство set to Details, вы можете создайте вывод с несколькими столбцами. Иногда вам захочется последнего столбец ListView для определения размера самого себя чтобы занять все оставшееся пространство. Вы можно сделать это, установив столбец ширина до магического значения -2.
В следующем примере имя элемент управления ListView - lvSample:
[c#] private void Form1_Load(object sender, System.EventArgs e) { SizeLastColumn(lvSample); } private void listView1_Resize(object sender, System.EventArgs e) { SizeLastColumn((ListView) sender); } private void SizeLastColumn(ListView lv) { lv.Columns[lv.Columns.Count - 1].Width = -2; }Редактировать:
Программно вы можете сделать это с помощью собственного реализованного алгоритма. Проблема в том, что представление списка не знает, какие столбцы вы хотите изменить, а какие нет. Таким образом, вам придется в методе resize (или в методе resizeEmd) указать все изменения размера столбцов. Таким образом, вы вычисляете всю ширину listview, а затем пропорционально делите значение между всеми колоннами. Ширина ваших столбцов кратна 50. Таким образом, у вас есть вся ширина listview 15*х (x=50 в состоянии по умолчанию. Я рассчитал значение 15 исходя из количества ваших колонок и их ширины) условных единиц. При изменении размера формы можно вычислить новый
x = ListView.Width/15, а затем установить ширину каждого столбца в нужное значение, так чтоprivate void SizeLastColumn(ListView lv) { int x = lv.Width/15 == 0 ? 1 : lv.Width/15; lv.Columns[0].Width = x*2; lv.Columns[1].Width = x; lv.Columns[2].Width = x*2; lv.Columns[3].Width = x*6; lv.Columns[4].Width = x*2; lv.Columns[5].Width = x*2; }
Вот мое решение;
Вместо события resize я предпочитаю resizeEnd формы, так что код будет выполняться только один раз, когда изменение размера будет завершено.
private void Form1_ResizeEnd(object sender, EventArgs e) { this.ResizeColumnHeaders(); }Функция ResizeColumnHeaders устанавливает все столбцы, кроме последнего, в соответствие с содержимым столбца. Последняя колонка будет использовать магическое значение, на которое намекает LexRema.
private void ResizeColumnHeaders() { for (int i = 0; i < this.listView.Columns.Count - 1;i++ ) this.listView.AutoResizeColumn(i, ColumnHeaderAutoResizeStyle.ColumnContent); this.listView.Columns[this.listView.Columns.Count - 1].Width = -2; }Также не забудьте вызвать ResizeColumnHeaders() после загрузки исходных данных;
private void Form1_Load(object sender, EventArgs e) { this.LoadEntries(); this.ResizeColumnHeaders(); }Еще одна вещь, чтобы предотвратить мерцание в то время как столбцы-изменяет размер, вам нужно дважды буферизировать listview.
public Form1() { InitializeComponent(); this.listView.DoubleBuffer(); }DoubleBuffer () на самом деле является расширением для удобного использования.
public static class ControlExtensions { public static void DoubleBuffer(this Control control) { // http://stackoverflow.com/questions/76993/how-to-double-buffer-net-controls-on-a-form/77233#77233 // Taxes: Remote Desktop Connection and painting: http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx if (System.Windows.Forms.SystemInformation.TerminalServerSession) return; System.Reflection.PropertyInfo dbProp = typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); dbProp.SetValue(control, true, null); } }
Вы можете изменить размер столбцов по содержимому, как описано здесь, или вы должны прослушать событие Resize ListView и задать размер столбцов во время выполнения.
Простое решение, которое принимает listview и индекс столбца, который вы хотите изменить автоматически, так что размер всей клиентской области listview используется до последнего пикселя, не больше и не меньше, то есть не появляется уродливая горизонтальная полоса прокрутки, даже если изменение размера делает элемент управления меньше.
Вы хотите вызвать этот метод из вашего обработчика событийResize , а также после добавления элемента в случае, если вертикальная полоса прокрутки появилась после добавления большего количества строк, чем контроль имеет место для вертикали.
Я не согласен с идеей реагировать на событие ResizeEnd вместо этого, как упоминалось в одном из других сообщений, поскольку это не выглядит хорошо на экране, если Windows настроена на рисование окон при перемещении и изменении размера. Расчет выполняется быстро, поэтому он не создает никаких проблем для непрерывного изменения размера.
static private void ResizeAutoSizeColumn(ListView listView, int autoSizeColumnIndex) { // Do some rudimentary (parameter) validation. if (listView == null) throw new ArgumentNullException("listView"); if (listView.View != View.Details || listView.Columns.Count <= 0 || autoSizeColumnIndex < 0) return; if (autoSizeColumnIndex >= listView.Columns.Count) throw new IndexOutOfRangeException("Parameter autoSizeColumnIndex is outside the range of column indices in the ListView."); // Sum up the width of all columns except the auto-resizing one. int otherColumnsWidth = 0; foreach (ColumnHeader header in listView.Columns) if (header.Index != autoSizeColumnIndex) otherColumnsWidth += header.Width; // Calculate the (possibly) new width of the auto-resizable column. int autoSizeColumnWidth = listView.ClientRectangle.Width - otherColumnsWidth; // Finally set the new width of the auto-resizing column, if it has changed. if (listView.Columns[autoSizeColumnIndex].Width != autoSizeColumnWidth) listView.Columns[autoSizeColumnIndex].Width = autoSizeColumnWidth; }
Используйте это
Private Sub ListView1_Resize(sender As Object, e As EventArgs) Handles ListView1.Resize Dim k = ListView1.Width - 10 Dim i = k / 3 ListView1.Columns(0).Width = k - i ListView1.Columns(1).Width = i / 2 ListView1.Columns(2).Width = i / 2 End SubТри колонки один побольше два поменьше с одинаковым размером
Comments