10

ive been working on this for a few days, but cant seem to come up with a solution

i have code on a timer that refreshes the DataGrid every few seconds

i tried many refresh options, but in the end they all lose the users focus and sometimes also the SelectedItem

heres my code:

        AddHandler bw.RunWorkerCompleted, Function(sender As Object, e As ComponentModel.RunWorkerCompletedEventArgs)
                                              Dim lst = e.Result
                                              Dim lst2 = CType(lst, List(Of Object)).OfType(Of INotifyPropertyChanged)()
                                              'If Items.Count = 0 Then
                                              Dim a = SelectedItem
                                              Collection.Clear()
                                              Collection.AddRange(lst2)
                                              SelectedItem = a
                                              'ItemsSource = lst
                                              'End If
                                              'For Each rw In lst
                                              '    Dim mtch = Collection.Where(Function(x) x.GetHashCode = rw.GetHashCode)

                                              'Next

i left the comments so you can see the different approaches i tried

RESULTS:

if i directly set the ItemsSource with the result (as in the comment), then the SelectedItem and the Keyboard.FocusedElement keep steady till the end of the above code, but somewhere between the end of this code and the next tick they are both turned into Nothing

if i go with the ObservableCollection then SelectedItem is lost as soon as i clear the collection and Keyboard.FocusedElement is only lost sometime between ticks. though the SelectedItem can be retained here with a temp backing variable

so the point is how do we refresh the items from the db while still keeping (most-importantly) the keyboard focus

and yes, i know that ObservableCollections are not "made" to be reset. in fact, im not really interested in using one. it just has one plus of keeping the SelectedItem

P.S. i also tried hooking into several events (OnItemsSourceChanged,SourceUpdated...) but they weren't fired at the right time, or didnt fire at all

any ideas?

id really most appreciate

thank you

horns
  • 1,843
  • 1
  • 19
  • 26
Yisroel M. Olewski
  • 1,560
  • 3
  • 25
  • 41
  • check this - http://stackoverflow.com/questions/12808479/updating-listbox-without-losing-selected-item-wpf – Indhi May 27 '13 at 10:18
  • 1
    thanks, after no one answered here, i did post in msdn and got a pretty good answer, its working good enough for now. the link you set has no news, i have also considered updating the records 1 by 1. but havent gotten around to it yet. thanks anyway for taking an interest! – Yisroel M. Olewski May 28 '13 at 06:52
  • hello Yisman, can you please post the link where I can see the solution. it will help me also to learn. thanks :) – Indhi May 28 '13 at 07:59
  • 2
    http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/faa24175-0cb2-4a44-8c02-a0eca893c028 – Yisroel M. Olewski May 29 '13 at 06:53
  • In my opinion, the only two possible solutions here are: A) either you keep the CurrentCell info in a backing field and re-set it after every ItemsSource change, or B) don't change the collection at all and "simply" iterate through the items refreshing them with their new values. – almulo Jun 02 '15 at 16:05

3 Answers3

1

You need to use the SelectedIndex instead of the SelectedItem property of the DataGrid. Save the selected index before replacing ItemsSource with lst.

The reason SelectedItem does not work is that this is a reference to an object in the list you are replacing.

Perhaps you don't want to use index because the focused item might move up or down based on database update. In that case you will need to use the key to find the index of the record in the new list.

If you can't use the index or don't have a key then I can't think of a good way to do this.

Also it seems to me that replacing the list completely will lead to other problems. If the user is typing something into DataGrid cell and you replace the list under them, they will lose their edits.

AQuirky
  • 4,691
  • 2
  • 32
  • 51
  • thnaks. in the end i built an `ObservableCOllection`. that becomes the itemsource, then i update individual properties in the observablecollection and alls fine. thanks! – Yisroel M. Olewski Feb 24 '17 at 08:44
0

Your best option is the following:

When a user makes a selection, save the index or the current selecteditem in a variable.

in the CollectionChanged even in your collection re assign the selected item to whatever you saved before in the variable. The CollectionChanged event is triggered after any change in the collection so you will be able to do post processing which is in this case reassigning the selected item.

Omar Zaarour
  • 302
  • 3
  • 9
0

Have you verified that you have the same instance of the object? I.e. SelectedItem must exist in lst2. Otherwise you need to find the matching item in the new list and use that object instead.

l33t
  • 18,692
  • 16
  • 103
  • 180
  • hi. in the end i ended up only changing the properties of thos records that were actually changed in the db. that did the trick. thanks anyway. – Yisroel M. Olewski Dec 18 '16 at 08:17