[C#] Ausgewählte ListViewItems per Button-Klick verschieben

// funktioniert auch mit MultiSelect = true
// n items nach oben verschieben
private void btnUp_Click(object sender, EventArgs e)
{
    int ilevel = 0;

    ListView1.BeginUpdate();

    if (ListView1.SelectedItems.Count -> 0)
    {
        for (int i = 0; i < ListView1.Items.Count; i++)
        {
            if (ListView1.Items[i].Selected)
            {
                ilevel = i;
                if (ilevel - 1 ->= 0)
                {
                    ListViewItem lvitem = ListView1.Items[i];
                    ListView1.Items.Remove(lvitem);
                    ListView1.Items.Insert(ilevel - 1, lvitem);
                }
            }
        }
    }

    ListView1.EndUpdate();
}
// n items nach unten verschieben
private void btnDown_Click(object sender, EventArgs e)
{
    int iLevel = 0;

    ListView1.BeginUpdate();

    if (ListView1.SelectedItems.Count -> 0)
    {
        for (int i = ListView1.Items.Count - 1; i ->= 0; i--)
        {
            if (ListView1.Items[i].Selected)
            {
                iLevel = i;
                if (iLevel + 1 < ListView1.Items.Count)
                {
                    ListViewItem lvItem = ListView1.Items[i];
                    ListView1.Items.Remove(lvItem);
                    ListView1.Items.Insert(iLevel + 1, lvItem);
                }
            }
        }
    }

    ListView1.EndUpdate();
}

[C#] Tooltip beim Überfahren eines ListViewSubItem anzeigen

// auf dem Formular muss sich noch ein ToolTip namens "toolTip" befinden
// letztes SubItem unter der Maus
private ListViewItem.ListViewSubItem _currentsubitem = null;
// Offset für Tooltip
private const int TOOLTIPP_Y_OFFSET = 24;

private void ListView1_MouseMove(object sender, MouseEventArgs e)
{
    ListView lv = sender as ListView;

    if (lv != null)
    {
        ListViewHitTestInfo htInfo = lv.HitTest(e.X, e.Y);
        if (htInfo != null)
        {
            if (htInfo.Item != null && htInfo.SubItem != null)
            {
                // wenn Subitem in Spalte 2 (Index == 1) gewählt
                if (htInfo.Item.SubItems.IndexOf(htInfo.SubItem) == 1)
                {
                    if (_currentsubitem != htInfo.SubItem)
                    {
                        toolTip.Show(htInfo.Item.Tag as string, lv, e.X, e.Y + TOOLTIPP_Y_OFFSET);
                        _currentsubitem = htInfo.SubItem;
                    }
                }
                else
                {
                    toolTip.Hide(lv);
                    _currentsubitem = null;
                }
            }
            else
            {
                toolTip.Hide(lv);
                _currentsubitem = null;
            }
        }
    }
}

private void ListView1_MouseLeave(object sender, EventArgs e)
{
    ListView lv = sender as ListView;

    if (lv != null)
    {
        toolTip.Hide(lv);
        _currentsubitem = null;
    }
}

UpDown-Button in einer ListView-Zelle (SubItem) anzeigen

Der UpDown-Button muss zur Designzeit auf dem Listview vorhanden sein!

// Eigenschaften des UpDownButtons setzen
UDBtn.BorderStyle = BorderStyle.None;
UDBtn.Visible = false;
UDBtn.ValueChanged += new System.EventHandler(UDBtn_ValueChanged);

// Ereignis ItemSelectionChanged des ListViews behandeln
private void ListView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
    if (e.IsSelected)
    {
        this.SetBtn(e.Item);
        UDBtn.Visible = true;
    }
    else
    {
        UDBtn.Visible = false;
        e.Item.SubItems[ListView1.Columns.Count - 1].Text = UDBtn.Value.ToString();
    }
}

// Funktion setzt den Button in die akt. Zeile und jeweils letzte Spalte (ListView1.Columns.Count - 1) des ListViews
// Werte für X- und Y-Offset müssen ggf. Angepasst werden
private void SetBtn(ListViewItem lvi)
{
    int iLeft = 0;

    if (lvi != null)
    {
        if (lvi.Selected)
        {
            // adjust position values here, to fit correctly
            UDBtn.Top = 38 + lvi.Position.Y - 20;

            for (int iCol = 0; iCol < ListView1.Columns.Count; iCol++)
            {
                iLeft += ListView1.Columns&#91;iCol&#93;.Width;
            }

            UDBtn.Left = iLeft - 39;
            UDBtn.Width = ListView1.Columns&#91;ListView1.Columns.Count - 1&#93;.Width - 1;
            UDBtn.Value = decimal.Parse(lvi.SubItems&#91;ListView1.Columns.Count - 1&#93;.Text);
        }
    }
    else
    {
        UDBtn.Visible = false;
    }
}

// Ereignis ValueChanged des Buttons
private void UDBtn_ValueChanged(object sender, System.EventArgs e)
{
    ListViewItem lvi = (ListView1.SelectedItems.Count -> 0) ? lvi = ListView1.SelectedItems[0] : null;

    if (lvi != null)
    {
        lvi.SubItems[ListView1.Columns.Count - 1].Text = UDBtn.Value.ToString();
    }
}

Eigene Textformatierungen und Bitmaps im ListView darstellen (OwnerDraw)

ListView1.OwnerDraw = true;
ListView1.View = View.Details;

// ListView-Überschriften zeichnen
private void ListView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
    e.DrawBackground();

    StringFormat sf = new StringFormat();
    sf.Alignment = StringAlignment.Center;

    // da StringAlignment.Center, muss die Breite für die Darstellung durch 2 geteilt werden
    int iWidth = ListView1.Columns[e.ColumnIndex].Width / 2;
    
    // Header-String zentriert, schwarz und fett zeichnen
    e.Graphics.DrawString(e.Header.Text, new Font("Microsoft Sans Serif", 8.25F, FontStyle.Bold), Brushes.Black, e.Bounds.X + iWidth, e.Bounds.Y, sf);
}

// ListView-Subitems zeichnen
private void ListView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
    StringFormat sf = new StringFormat();
    sf.Alignment = StringAlignment.Center;

    switch (e.ColumnIndex)
    {
        case 0:
            // Subitem 0 beinhaltet ein Bitmap
            Bitmap b = new Bitmap(@"c:\temp\test.jpg");
            e.Graphics.DrawImage(b, e.Bounds.X, e.Bounds.Y);
            break;
        default:
            // für alle anderen SubItems
            // halbe Spaltenbreite der akt. Spalte ausrechnen
            int iWidth = ListView1.Columns[e.ColumnIndex].Width / 2;
            // halbe Zellenhöhe ausrechnen
            int iHeight = (int)(ListView1.Font.SizeInPoints / 2.0);
            // String mit akt. Subitem-Text zeichnen
            e.Graphics.DrawString(e.SubItem.Text, new Font("Microsoft Sans Serif", 8.25F, FontStyle.Regular), Brushes.Black, e.Bounds.X + iWidth, e.Bounds.Y + iHeight, sf);
            break;
    }
}

// ListView-Item Hintergrund speziell färben, wenn focusiert
private void ListView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
    if (e.State == ListViewItemStates.Focused)
    {
        e.Graphics.FillRectangle(Brushes.Beige, e.Bounds);
        e.DrawFocusRectangle();
    }
}

ListViewItems einer Gruppe zuordnen

  • ab .Net Framework 2.0 hat ein ListView die zusätzliche Eigenschaft “Groups”
  • im Objekteditor kann man sich eine Liste mit Gruppen erstellen, zu welchen man einzelne ListViewItems zuordnen kann
  • die ListViewItems werden innerhalb der Gruppe im ListView unter einer Art Zwischenüberschrift angeordnet
// 1. Item der 1. Gruppe zuordnen
ListView1.Items.Add(new ListViewItem(new string[] { "Text1", "Text2" }, ListView1.Groups[0]));
// 2. Item der 2. Gruppe zuordnen
ListView1.Items.Add(new ListViewItem(new string[] { "Text1", "Text2" }, ListView1.Groups[1]));

Auswählen von ListView SubItems mittels ComboBox

// auf dem Formular befindet sich ein ListView mit Namen ListView1
public partial class Form1 : Form
{
    // die Combobox mit der Editiert wird
    private ComboBox _cbEdit = new ComboBox();
    
    // Verweise auf das ListViewElement
    private ListViewItem.ListViewSubItem _lvSubItemEdit = null;
    
    public frmMain()
    {
        InitializeComponent();
        
        // ComboBox initialisieren
        _cbEdit.Visible = false;
        // Werte nur anzeigen, kein Editieren zulassen
        _cbEdit.DropDownStyle = ComboBoxStyle.DropDownList;
        // Eventhandler für die Textbox hinzufügen
        _cbEdit.Leave += new EventHandler(_cbEdit_Leave);

        // ein paar Beispielwerte
        _cbEdit.Items.Add("0.5");
        _cbEdit.Items.Add("0.8");
        _cbEdit.Items.Add("0.9");

        // der Form hinzufügen
        this.Controls.Add(_cbEdit);
    }
   
    // Event für das Verlassen der Combobox per Maus
    void _cbEdit_Leave(object sender, EventArgs e)
    {
        if (_lvSubItemEdit != null)  
        {
            if (_cbEdit.SelectedItem != null)
            {
                _lvSubItemEdit.Text = _cbEdit.SelectedItem.ToString();
            }
        }

        _cbEdit.Visible = false; 
    }

    // Event des ListViews
    // zum Merken des zuletzt angeklickten ListViewItems
    // und zum Plazieren der Combobox
    private void ListView1_MouseUp(object sender, MouseEventArgs e)
    {
        ListViewHitTestInfo htInfo = ListView1.HitTest(e.X, e.Y);
        if (htInfo != null)
        {
            if (htInfo.Item != null && htInfo.SubItem != null)
            {
                // wenn Subitem in Spalte 2 (Index == 1) gewählt
                // dann ComboBox anzeigen
                if (htInfo.Item.SubItems.IndexOf(htInfo.SubItem) == 1)
                {
                    _lvSubItemEdit = htInfo.SubItem;

                    _cbEdit.Top = ListView1.Top + _lvSubItemEdit.Bounds.Top + 2;
                    _cbEdit.Left = ListView1.Left + _lvSubItemEdit.Bounds.Left + 2;

                    _cbEdit.Width = _lvSubItemEdit.Bounds.Width;
                    _cbEdit.Height = _lvSubItemEdit.Bounds.Height;

                    _cbEdit.SelectedIndex = _cbEdit.Items.IndexOf(_lvSubItemEdit.Text);

                    _cbEdit.Visible = true;
                    _cbEdit.BringToFront();
                    _cbEdit.Focus();
                }
                else
                {
                    _lvSubItemEdit = null;
                }
            }
        }
    }
}

Editieren von ListView SubItems mittels TextBox

// auf dem Formular befindet sich ein ListView mit Namen ListView1
// alle Zellen des Formulars können editiert werden
public partial class Form1 : Form
{
    // die Textbox mit der Editiert wird
    private TextBox _tbEdit = new TextBox();
    
    // Verweise auf das ListViewElement
    private ListViewItem.ListViewSubItem _lvSubItemEdit = null;
    
    public frmMain()
    {
        InitializeComponent();

        // Textbox initialisieren
        _tbEdit.Visible = false;
        // Rahmen entfernen, damit die Textbox genau in die Zelle des ListViews passt
        _tbEdit.BorderStyle = BorderStyle.None;
        // Eventhandler für die Textbox hinzufügen
        _tbEdit.Leave += new EventHandler(_tbEdit_Leave);
        _tbEdit.KeyPress += new KeyPressEventHandler(_tbEdit_KeyPress);
        
        // der Form hinzufügen
        this.Controls.Add(_tbEdit);
    }
    
    // Event des ListViews
    // zum Merken des zuletzt angeklickten ListViewItems
    private void ListView1_MouseUp(object sender, MouseEventArgs e)
    {
        ListViewHitTestInfo htInfo = ListView1.HitTest(e.X, e.Y);
        if (htInfo != null)
        {
            if (htInfo.Item != null && htInfo.SubItem != null)
            {
                _lvSubItemEdit = htInfo.SubItem;
            }
        }
    }
    
    // bei Doppelklick auf ein SubItem die Textbox anzeigen
    private void ListView1_DoubleClick(object sender, EventArgs e)
    {
        // Größe anpassen
        _tbEdit.Top = ListView1.Top + _lvSubItemEdit.Bounds.Top + 2;
        _tbEdit.Left = ListView1.Left + _lvSubItemEdit.Bounds.Left + 2;
        _tbEdit.Width = _lvSubItemEdit.Bounds.Width;
        _tbEdit.Height = _lvSubItemEdit.Bounds.Height;
        // Inhalt übergeben
        _tbEdit.Text = _lvSubItemEdit.Text;
        // anzeigen
        _tbEdit.Visible = true;
        _tbEdit.BringToFront();
        _tbEdit.Focus();
    }

    // Event für den Tastendruck im Textfeld
    private void _tbEdit_KeyPress(object sender, KeyPressEventArgs e)
    {
        switch (e.KeyChar)
        {
            case (char)(int)Keys.Escape:
                // bei Escape Eingabe nicht übernehmen
                EndEditing(false);
                break;
            case (char)(int)Keys.Enter:
                // bei Escape Eingabe übernehmen
                EndEditing(true);
                break;
        }
    }

    // Event für das Verlassen des Textfeldes per Maus
    // die Eingabe im Textfeld wird nicht übernommen
    private void _tbEdit_Leave(object sender, EventArgs e)
    {
        EndEditing(false);
    }

    // Aktion beim Verlassen des Textfeldes
    private void EndEditing(bool AcceptChanges)
    {
        if (_lvSubItemEdit != null)
        {
            if (AcceptChanges)
            {
                // bei "Enter", den Text übernehmen
                _lvSubItemEdit.Text = _tbEdit.Text;
            }
        }

        // Textbox ausblenden
        _tbEdit.Visible = false;
    }
}