When an item is inserted into a ListView, how can I automatically "select" it (programmatically)

When an item is inserted into a ListView, how can I automatically "select" it (programmatically)?

I want the item that was just inserted to go into "select" mode. I know I probably have to catch the "OnItemInserted" event and I know I can do something like ListViewItem.Selected=true. But, how do I get the (index of the) item that was just inserted?
dbaGrantAsked:
Who is Participating?
 
pschramaConnect With a Mentor Commented:
Well, you can't select the record in the ItemInserted event since you don't have access to either its ID or its index.

In this situation, you can get the ID from the inserted object in your insert method, after inserting it. Then the insert method can return that value, making it available in the ObjectDataSource.OnInserted event. Then you have to store that id so it can be accessed by the ObjectDataSource selecting method.

For a rough example, see the attached code.
// Sample insert method, returns the id of the inserted record
public static int InsertSalesRep(string name, string email)
{
   SalesDataContext context = new SalesDataContext();

   SalesRep newSalesRep = new SalesRep();
   newSalesRep.Name = name;
   newSalesRep.Email = email;

   context.SalesReps.InsertOnSubmit(newSalesRep);
   context.SubmitChanges();
   
   // after the insert, the object will have its id assigned
   return newSalesRep.ID;
}

// Sample select method, returns list of salesreps
public static List<SalesRep> InsertSalesRep()
{
   SalesDataContext context = new SalesDataContext();

   return context.SalesReps.ToList();
}

// private variable to hold the new id
private int _insertID = 0;

// inserted event, places the returned id into private variable
public void ObjectDataSource1_OnInserted(object source, ObjectDataSourceStatusEventArgs e)
{
   _insertID = (int)e.ReturnValue;
}

// selected event, finds index for inserted item and sets listview's selectedindex
protected void ObjectDataSource1_Selected(object sender, ObjectDataSourceStatusEventArgs e)
{
   if (_insertID != 0)
   {
      // Get the list returned by the select method
      List<SalesRep> salesReps = (List<SalesRep>)e.ReturnValue;

      // Find the index of the new record and set it
      int index = salesReps.FindIndex(delegate(SalesRep sr) { return sr.ID == _insertID; });
      SalesRepsList.SelectedIndex = index;
   }
}

Open in new window

0
 
pschramaCommented:
It's not quite as simple as that, I'm afraid.

First off, you need a way to get the ID of the inserted data. How, depends on your method of inserting the data.
For example, if you use your own method to insert a record with an SqlDataReader, you can append "; SELECT SCOPE_IDENTITY()" to your query and get the resulting ID by running the query with ExecuteScalar(). If you use linq to sql, it's a simple matter of checking the object id after you have called InsertOnSubmit(record) and SubmitChanges().

Once you have this ID, you can find out what index this record is on. But again, this depends on how you get your data. If your data is in the form of a list of objects (either built yourself or by linq to sql), you can loop through the list to find the record and determine its index.

For example...

int newPersonIndex = -1; // Default, no selection
List<Person> persons = GetPersons();
Person newPerson = persons.SingleOrDefault(p => p.Id == newPersonID); // using Linq to find the new record with the new id
if (newPerson != null)
{
   newPersonIndex = persons.IndexOf(newPerson); // get the index
}

personsListView.SelectedIndex = newPersonIndex;
personListView.DataSource = persons;
personListView.DataBind();

To give a proper answer, I'll need to know how exactly you are inserting data, selecting data, and binding it to the listview (programmatically, or by sql/object/linqdatasource).
0
 
mikebirtCommented:
Hi,

the previous code example covers one acceptable approach. Another is to use ObservableCollections as your datasource. This would allow you to hook into the collection changed events, the EventArgs of which provide you the index of the new item (in your datasource). If you allow ordering within your UI then you're back to searching for the Id to match... however, if you're not, this is a good solution. BTW, the new item is provided by the event args so that will aid the Id search should you need to do that.

the code example here is purely to illustrate the observable collection and use of it's collection changed event. ObservableCollection lives in the System.Collections.ObjectModel namespace.

HTH

Mike
        private void SetupDataSource()
        {
            ObservableCollection<string> myCollection = new ObservableCollection<string>();
            myCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(myCollection_CollectionChanged);
        }

        private void myCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
            {
                string newItem = (string)e.NewItems[0];
                // selectedIndex = e.NewStartingIndex 
            }
        }

Open in new window

0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
dbaGrantAuthor Commented:
We are using LINQ to SQL and the ListView is bound with an "ObjectDataSource". I inherited this code and I am just now getting to understand LINQ to SQL, that is part of the reason I am struggling with this change.

I added:   OnItemInserted="SalesRepsList_ItemInserted"  to the ListView definition thinking I could "select" the record just added right in that method (is that the right place??), but as I noted in the original text I haven't been able to figure out how to determine the ID and therefore the list index.

Thanks for the help!

0
 
dbaGrantAuthor Commented:
One question... whats going to fire the "ObjectDataSource1_Selected"? Will it fire automatically after the insert?

Let me give a little more info... right now, when the user selects a record, the select function of the ListView opens a page with multi tabs to the user can enter some "child" records for he record they just entered. What I am trying to do is go directly to that "select" mode right after the user enters a record, so the user doesn't have to go back to the list of records, then scroll down and find the record he just entered, select it and then have to enter those "child" records from the enabled tabs.

Make sense?
0
 
dbaGrantAuthor Commented:
I should also mention that the website is built with a "layered" architecture. The Data layer is a seperatly compiled layer accessed via a DLL. Of course, I could create a special Insert method for this particular use and I don't even necessarily have to put it in that "data layer", but I just thought I would throw that out there so you have a better understanding of what I am dealing with.

Which, come to think of it.. The list of "SalesReps" is persisted in the application. I might be able to forgo the changed to the Insert method and on the OnInserted, just grab the latest (largest) ID from the list. hmmm....
0
 
dbaGrantAuthor Commented:
This worked!
0
 
pschramaCommented:
ObjectDataSource1_Selected will fire automatically when the ListView is databound, if the ListView has the datasourceID set to ObjectDataSource1.

If the SalesRep list is always in memory in an application or global setting, then you could check there directly yes. You'd still need to have an insert and select method though, since the ObjectDataSource uses those.
0
All Courses

From novice to tech pro — start learning today.