Add Item to Listview Control

Add item to Listview control

I have done it like this and it seems to work:

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
string[] row = { textBox1.Text, textBox2.Text, textBox3.Text };
var listViewItem = new ListViewItem(row);
listView1.Items.Add(listViewItem);
}
}

How to add list items to a ListView in C#winform?

To make it multicolumn:

1) set the ListView into Details mode:

    listView1.View = View.Details;

2)set up your three columns:

    listView1.Columns.Add("Column1Name");
listView1.Columns.Add("Column2Name");
listView1.Columns.Add("Column3Name");

3) add your items:

    listView1.Items.Add(new ListViewItem(new string[]{"John dsfsfsdfs ", "1" , "100"}));

4) To make it more viewable try:

listView1.GridLines = true;

5) To hide columns headers:

 listView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;

Add item to Listview from function

So according to your requirements try this.

private void button1_Click(object sender, EventArgs e)
{
keyword();
}
// Non static so that you can access ListView1
public void keyword()
{
string country = "";
string key = "1070";

//Goto GetHtmlAsync
GetHtmlAsync(key, country);
}
// Non static
public async void GetHtmlAsync(string key, string country)
{
//GetHtmlAsync
var url = "https://www.test.com/search?county=" + country + "&q=" + key;

var httpClient = new HttpClient();
var html = await httpClient.GetStringAsync(url);

var htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(html);

//This is grabbed from HtmlDocument (list)
var id = "58756";
var seller = "Test";
var product = "GTX 1070";
var betTime = "10:10";
var price = "100";
var shipping = "4";

string[] row = { id, seller, product, betTime, price + shipping, url };
var listViewItem = new ListViewItem(row);
listView1.Items.Add(listViewItem);
}

How to speed adding items to a ListView?

I took a look at the source code for the list view and I noticed a few things that may make the performance slow down by the factor of 4 or so that you're seeing:

in ListView.cs, ListViewItemsCollection.AddRange calls ListViewNativeItemCollection.AddRange, which is where I began my audit

ListViewNativeItemCollection.AddRange (from line: 18120) has two passes through the entire collection of values, one to collect all the checked items another to 'restore' them after InsertItems is called (they're both guarded by a check against owner.IsHandleCreated, owner being the ListView) then calls BeginUpdate.

ListView.InsertItems (from line: 12952), first call, has another traverse of the entire list then ArrayList.AddRange is called (probably another pass there) then another pass after that. Leading to

ListView.InsertItems (from line: 12952), second call (via EndUpdate) another pass through where they are added to a HashTable, and a Debug.Assert(!listItemsTable.ContainsKey(ItemId)) will slow it further in debug mode. If the handle isn't created, it adds the items to an ArrayList, listItemsArray but if (IsHandleCreated), then it calls

ListView.InsertItemsNative (from line: 3848) final pass through the list where it is actually added to the native listview. a Debug.Assert(this.Items.Contains(li) will additionally slow down performance in debug mode.

So there are A LOT of extra passes through the entire list of items in the .net control before it ever gets to actually inserting the items into the native listview. Some of the passes are guarded by checks against the Handle being created, so if you can add items before the handle is created, it may save you some time. The OnHandleCreated method takes the listItemsArray and calls InsertItemsNative directly without all the extra fuss.

You can read the ListView code in the reference source yourself and take a look, maybe I missed something.

In the March 2006 issue of MSDN Magazine there was an article called Winning Forms: Practical Tips for Boosting The Performance of Windows Forms Apps.

This article contained tips for improving the performance of ListViews, among other things. It seems to indicate that its faster to add items before the handle is created, but that you will pay a price when the control is rendered. Perhaps applying the rendering optimizations mentioned in the comments and adding the items before the handle is created will get the best of both worlds.

Edit: Tested this hypothesis in a variety of ways, and while adding the items before creating the handle is suuuper fast, it is exponentially slower when it goes to create the handle. I played with trying to trick it to create the handle, then somehow get it to call InsertItemsNative without going through all the extra passes, but alas I've been thwarted. The only thing I could think might be possible, is to create your Win32 ListView in a c++ project, stuff it with items, and use hooking to capture the CreateWindow message sent by the ListView when creating its handle and pass back a reference to the win32 ListView instead of a new window.. but who knows what the side affects there would be... a Win32 guru would need to speak up about that crazy idea :)

listview add new item control

I have made a very simple layout with a listview. I add a button to the listview items and listen to the click to insert a new object before the button.

public MainWindow()
{
InitializeComponent();
listViewtst.Items.Add("test");
listViewtst.Items.Add("test2");
Button btn = new Button();
btn.Content = "+";
btn.Click += Btn_Click;
listViewtst.Items.Add(btn);
}

private void Btn_Click(object sender, RoutedEventArgs e)
{
listViewtst.Items.Insert(listViewtst.Items.Count - 1, "added by the btn");

}

Not sure if it is the best solution but this is how i would do it if no one showed me a better way :)


Other solution:

Code behind

    /// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ObservableCollection<MyObject> _windows = new ObservableCollection<MyObject>();

public MainWindow()
{
InitializeComponent();
Windows.Add(new MyObject { Title = "Collection Item 1" });
Windows.Add(new MyObject { Title = "Collection Item 2" });
}

private void Btn_Click(object sender, RoutedEventArgs e)
{

}

public ObservableCollection<MyObject> Windows
{
get { return _windows; }
set { _windows = value; }
}

private void button_Click(object sender, RoutedEventArgs e)
{
Windows.Add(new MyObject { Title = "From Btn" });
}
}

public class MyObject
{
public string Title { get; set; }
}

Xaml:

<Window x:Class="Move_To_Prd_Dev.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="246" Width="325" Name="UI">
<Window.Resources>
<CollectionViewSource Source="{Binding ElementName=UI, Path=Windows}" x:Key="YourMenuItems"/>
</Window.Resources>
<Grid DataContext="{Binding ElementName=UI}">
<ListBox x:Name="listTxt" HorizontalAlignment="Left" Height="163" Margin="10,29,0,0" VerticalAlignment="Top" Width="297">
<ListBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource YourMenuItems}}" />
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="button_Click"/>

</CompositeCollection>
</ListBox.ItemsSource>
</ListBox>

</Grid>

This uses CompositeCollection to add the button control to the list (with the advantage that the button is always Last)

Result

Manually insert an item into a ListView control

This error simply means that lstAuthors[i] is not a System.Web.UI.WebControls.ListViewDataItem (which is the only valid parameter for the ListView.Items.Add function.

In order to do this the way you are doing it now, you would need to initialize a ListViewDataItem, and use dummy values for the dataIndex parameter (since you don't have an underlying indexed datasource):

ListViewDataItem newItem = new ListViewDataItem(dataIndex, displayIndex);

To be honest, this doesn't really seem like the right way to use the ListView control. Maybe you could tell us what you're trying to accomplish, and we could help out with another approach.


Here is a really trimmed down, basic approach to doing what you would like to do. You basically maintain a generic List<T> as your datasource, and bind that to your ListView. This way you can handle all of the details of maintaining the contents of your ListView, but you can still use the built in power of the databinding.

Basic markup (a ListView with one item in it's ItemTemplate, a DropDownList to select items from, and a Button for adding those items to the ListView):

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ListView ID="ListView1" runat="server">
<ItemTemplate>
<div>
<asp:Label ID="AuthorNameLbl" runat="server" Text='<%# Eval("AuthorName") %>'></asp:Label>
</div>
</ItemTemplate>
</asp:ListView>
<br />
<asp:DropDownList ID="DropDownList1" runat="server">
<asp:ListItem>Stephen King</asp:ListItem>
<asp:ListItem>Mary Shelley</asp:ListItem>
<asp:ListItem>Dean Koontz</asp:ListItem>
</asp:DropDownList>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</asp:Content>

And code-behind:

// Honestly, this string  just helps me avoid typos when 
// referencing the session variable
string authorKey = "authors";

protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// If the session variable is empty, initialize an
// empty list as the datasource
if (Session[authorKey] == null)
{
Session[authorKey] = new List<Author>();
}
BindList();
}
}

protected void Button1_Click(object sender, EventArgs e)
{
// Grab the current list from the session and add the
// currently selected DropDown item to it.
List<Author> authors = (List<Author>)Session[authorKey];
authors.Add(new Author(DropDownList1.SelectedValue));
BindList();
}

private void BindList()
{
ListView1.DataSource = (List<Author>)Session[authorKey];
ListView1.DataBind();
}

// Basic author object, used for databinding
private class Author
{
public String AuthorName { get; set; }

public Author(string name)
{
AuthorName = name;
}
}


Related Topics



Leave a reply



Submit