web-dev-qa-db-fra.com

Ajuster les colonnes ListView pour s'adapter à WinForms

J'ai le problème de redimensionnement de visage des colonnes listview. Si vous ancre/amarrage la listview en Winform normal que l'ancre ou l'amarrage de listview fonctionne bien. Je veux dire que listview redimensionnera et s'adaptera aux formes de Win, à mesure que celles-ci seront maximisées, mais les colonnes que vous avez conçues dessus ne seront pas redimensionnées avec Listview.

Ma question est la suivante: Est-il possible de redimensionner les colonnes de listview avec listview pour s’adapter à la taille de winform?.

Code de conception 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);


    }
11
mahesh
  1. Un programme. Vous devrez le maintenir dans le code. 
  2. Vous pouvez ajuster la dernière taille de colonne dans votre liste de vues afin qu’elle soit automatiquement redimensionnée. Exemple net:

Dans un contrôle ListView, lorsque la propriété View Est définie sur Details, vous pouvez Créer une sortie sur plusieurs colonnes. Parfois, vous souhaiterez la dernière colonne De le ListView se redimensionne lui-même pour occuper tout l’espace restant. Vous pouvez Faire cela en réglant la largeur de la colonne Sur la valeur magique -2.

Dans l'exemple suivant, le nom Du contrôle ListView est 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;
}

MODIFIER:

Par programmation, vous pouvez le faire avec votre propre algorithme implémenté. Le problème est que la vue en liste ne sait pas quelles colonnes vous souhaitez redimensionner ou pas. Vous aurez donc dans la méthode resize (ou dans la méthode resizeEmd) pour spécifier toutes les modifications de taille des colonnes. Donc, vous calculez toute la largeur de la liste, puis divisez proportionnellement la valeur entre toutes les colonnes. La largeur de vos colonnes est multiple de 50. Vous avez donc toute la largeur de la vue liste de 15 * х (x = 50 dans l'état par défaut. J'ai calculé 15 valeurs en fonction du nombre de vos colonnes et de leur largeur) en unités conventionnelles. Lorsque le formulaire est redimensionné, vous pouvez calculer le nouveau x = ListView.Width/15, puis définir la largeur de chaque colonne sur la valeur requise. 

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;
}
28
Sasha Reminnyi

Voici ma solution.

Au lieu d'un événement de redimensionnement, je préfère redimensionner à la fin du formulaire, afin que le code ne s'exécute qu'une seule fois lorsque le redimensionnement est terminé.

private void Form1_ResizeEnd(object sender, EventArgs e)
{
    this.ResizeColumnHeaders();
}

La fonction ResizeColumnHeaders définit toutes les colonnes sauf la dernière sur le contenu de colonne. La dernière colonne utilisera la valeur magique suggérée par 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;
}

N'oubliez pas non plus d'appeler ResizeColumnHeaders () après avoir chargé vos données initiales;

private void Form1_Load(object sender, EventArgs e)
{            
    this.LoadEntries();
    this.ResizeColumnHeaders();
}

Une autre chose à faire est d’empêcher le scintillement pendant le redimensionnement des colonnes, vous devez mettre en double tampon la vue de liste.

public Form1()
{
    InitializeComponent();            
    this.listView.DoubleBuffer();            
}

DoubleBuffer () est en fait une extension facile à utiliser.

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);
    }
}
10
HuseyinUslu

Une solution simple qui prend une liste et l’index de la colonne que vous souhaitez redimensionner automatiquement, de sorte que la taille de la zone cliente de la liste complète soit utilisée au dernier pixel, ni plus ni moins, c’est-à-dire qu’aucune barre de défilement horizontale moche ne s’affiche même si le redimensionnement réduit le contrôle.

Vous souhaitez appeler cette méthode à partir de votre Resize gestionnaire d'événements, ainsi que après l'ajout d'un élément au cas où une barre de défilement verticale s'afficherait après l'ajout de davantage de lignes que le contrôle ne le permet verticalement.

Je ne suis pas d'accord avec l'idée de réagir à l'événement ResizeEnd, comme mentionné dans l'un des autres articles, car cela n'a pas l'air sympa à l'écran si Windows est configuré pour dessiner des fenêtres lors du déplacement et du redimensionnement. Le calcul est rapide, il ne crée donc aucun problème pour redimensionner en continu.

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;
}
4
Søren L. Fog

Vous pouvez redimensionner les colonnes par contenu comme décrit ici ou vous devez écouter l’événement Resize d’un ListView et définir la taille des colonnes au moment de l’exécution.

2
Denis Palnitsky

utilisez ceci

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

trois colonnes un plus grand deux plus petit avec la même taille

0
aex