Hi,

I am new to c# windows application.
I have added a listview programatically to c# win form. I want to add a listview row (editable row) dynamically on click
of Add button so that user can type new items and save it.

Please see the code which adds a listview and adds some item to the list view.

private ListView listView1;
        private Button AddBtn;

        public Form1()
        {
            InitializeComponent();
            // adds listview to the form
            AddControls();
            // Adding products to the listview
            AddProducts();
        }
        private void AddControls()
        {
            listView1 = new ListView();
            listView1.Location = new System.Drawing.Point(0, 12);
            this.listView1.Name = "listView1";
            this.listView1.Size = new System.Drawing.Size(250, 175);
            this.listView1.TabIndex = 0;
            this.listView1.UseCompatibleStateImageBehavior = false;
            this.listView1.View = System.Windows.Forms.View.Details;

            // Adding listview header
            listView1.Columns.Add("Product name", 100);
            listView1.Columns.Add("Search string", 100);

            this.Controls.Add(listView1);

            // Adds a add button
            this.AddBtn = new System.Windows.Forms.Button();
            this.AddBtn.Location = new System.Drawing.Point(0, 211);
            this.AddBtn.Name = "AddBtn";
            this.AddBtn.Size = new System.Drawing.Size(75, 23);
            this.AddBtn.TabIndex = 2;
            this.AddBtn.Text = "Add";
            this.AddBtn.UseVisualStyleBackColor = true;

            this.Controls.Add(AddBtn);

        }

        // Adds products to the listview
        private void AddProducts()
        {
            IDictionary<string, string> products = GetProducts();
            foreach (var p in products)
            {
                ListViewItem lstItem = new ListViewItem(p.Key);
                lstItem.SubItems.Add(p.Value);
                listView1.Items.Add(lstItem);
            }
        }

        // Gets the products
        private IDictionary<string, string> GetProducts()
        {
            IDictionary<string, string> products = new Dictionary<string, string>();
            products.Add("product a", "a");
            products.Add("product b", "b");
            products.Add("product c", "c");
            products.Add("product d", "d");
            return products;
        }

Is it posible to add a new editable row to the listview so that user can type a new product name and new search string
and save it using another save button.

Thanks for the help. Your help will be heighly appriciated.

Thanks.
Regards

Dani AI

Generated

is right that DataGridView is built for inline editing, but if you must keep ListView you can still get a good UX. Two tricks help: enable label editing for column 0, and overlay a TextBox for subitems. ’s dialog idea is great for validation; the code below shows the inline alternative so users can add and edit in place.

Add a blank row and immediately start editing the first column:

// one-time setup
listView1.View = View.Details;
listView1.FullRowSelect = true;
listView1.LabelEdit = true;
AddBtn.Click += AddBtn_Click;

void AddBtn_Click(object sender, EventArgs e)
{
    var item = new ListViewItem("");   // Product name
    item.SubItems.Add("");             // Search string
    listView1.Items.Insert(0, item);   // top of list; use Add() for bottom
    item.Selected = true;
    listView1.EnsureVisible(item.Index);
    item.BeginEdit();                  // built-in edit for column 0
}

To edit other columns, place a TextBox over the clicked subitem:

TextBox editor;

public Form1()
{
    InitializeComponent();
    listView1.MouseDoubleClick += listView1_MouseDoubleClick;
}

void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
    var info = listView1.HitTest(e.X, e.Y);
    if (info.Item == null || info.SubItem == null) return;

    int sub = info.Item.SubItems.IndexOf(info.SubItem);
    if (sub == 0) { info.Item.BeginEdit(); return; }

    if (editor == null)
    {
        editor = new TextBox { BorderStyle = BorderStyle.FixedSingle, Visible = false };
        editor.Leave += commit;
        editor.KeyDown += (s, ke) => { if (ke.KeyCode == Keys.Enter) commit(s, EventArgs.Empty);
                                       if (ke.KeyCode == Keys.Escape) editor.Visible = false; };
        listView1.Controls.Add(editor);
    }

    editor.Bounds = info.SubItem.Bounds;
    editor.Text = info.SubItem.Text;
    editor.Tag = Tuple.Create(info.Item, sub);
    editor.Visible = true; editor.Focus(); editor.SelectAll();
}

void commit(object sender, EventArgs e)
{
    var t = (Tuple<ListViewItem,int>)editor.Tag;
    t.Item1.SubItems[t.Item2].Text = editor.Text;
    editor.Visible = false;
}

Notes:

  • Validate on commit or in your Save button by iterating listView1.Items.
  • Hide the editor if the list scrolls or columns resize to avoid misalignment.
  • For an "always-empty" add row, insert a blank item at the bottom after each commit.

Recommended Answers

All 7 Replies

The way you describe your problem, you need a DataGridView, not a ListView.
A ListView Is more of a displaying nature. Like what you see in the windows of Windows Explorer.

but the problem is, I can'nt use datagrid view...as this is an existing application where listview has been already used. So add new row on top of listview on click of add.
Please if posible let me know if i can do this??

You could use the button to show a dialog form with textboxes to get the info, validate the info to make sure it was entered right, then declare a new listviewitem, add the info from the dialog and add it to the listview item collection.

Is that mean that creating a new editable row is not posible with listview ???

It might be possible using the keypress event and always having an empty row right at the bottom. but then to keep it at the bottom, any time to want add a row you'd have to insert instead.

Here's some code you might be able to use This isn't a full implementation, but it should show you enough to do what you want. This is set up to use a default item with only a * as text and is the last item in the listview. When you click the listview, first the cursor changes to show you're in edit mode. What ever the user types will show as the text in the last item. when the user presses enter or clicks a btnAdd, an item with an * as text is added.

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            listView1.KeyPress += new KeyPressEventHandler(listview1_KeyPress);
            listView1.GotFocus +=new EventHandler(listView1_GotFocus);
            listView1.LostFocus += new EventHandler(listView1_LostFocus);
        }
        private void listView1_GotFocus(object sender, EventArgs e)
        {
            listView1.Cursor = Cursors.IBeam;
        }
        private void listView1_LostFocus(object sender, EventArgs e)
        {
            listView1.Cursor = Cursors.Arrow;
        }
        private void Addbtn_Click(object sender, EventArgs e)
        {
            if(listView1.Items[listView1.Items.Count-1].Text != "*")
                listView1.Items.Add("*");
        }
        private void listview1_KeyPress(object sender, KeyPressEventArgs e) 
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                button1.PerformClick();
                return;
            }
            if (char.IsLetterOrDigit(e.KeyChar) || char.IsPunctuation(e.KeyChar))
            {
                if (listView1.Items[listView1.Items.Count - 1].Text == "*")
                {
                    listView1.Items[listView1.Items.Count - 1].Text = e.KeyChar.ToString();
                }
                else
                    listView1.Items[listView1.Items.Count - 1].Text += e.KeyChar.ToString();
            }
        }
    }

oops typo, line 27 should read Addbtn.PerformClick();

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.