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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
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
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

pschramaCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP.NET

From novice to tech pro — start learning today.