0

From my ViewModel, I need to programmatically move the focus and highlight of a row in a WPF DataGrid. The DataGrid has just one column:

   <DataGrid Name="DgAdrType" 
   ItemsSource="{Binding ItemsLcv}"
   IsSynchronizedWithCurrentItem="True" 

    <DataGridTextColumn Header="   Description" 
    IsReadOnly="True" 
    CanUserSort="True" Binding="{Binding descr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

And in the datacontext ViewModel:

private IEnumerable<AdrTypeMdl> _itemsList;
ItemsLcv = CollectionViewSource.GetDefaultView(_itemsList) as ListCollectionView;

This works even though I don't have a property per se in the ViewModel for the data field "descr", because I bind the DataGrid's ItemSource.

In the ViewModel I can access the View DataGrid's ItemCollection of items by passing in that ItemCollection from the View like so:

<!-- Interaction for click selection -->
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotMouseCapture">
<i:InvokeCommandAction Command="{Binding SelObjChangedCommand}"
  CommandParameter="{Binding ElementName=DgAdrType, Path=Items}"/>
  </i:EventTrigger>
  </i:Interaction.Triggers>

And back in the ViewModel, I load the DataGrid items like so:

private ItemCollection _dgItems;
private void SelObjChanged(object theItems)
{if (theItems !=null)
{ _dgItems = theItems as ItemCollection;

I want to keep the cast to ItemCollection so that I can retain the DataGrid properties of that ItemCollection. The problem is the ItemCollection's IndexOf method is not working. I only get -1 when I try to find the index of one of the class object items by doing this.

  var idx = _dgItems.IndexOf(myobject);

EDIT ------- this is entire code of the method try IndesOf

private void HandleUpdateListEvent(Object myobject)
{AdrTypeMdl theNewItem = myobject as AdrTypeMdl;
bool co = _dgItems.Contains(theNewItem);
var idx = _dgItems.IndexOf(theNewItem);
_dgItems.MoveCurrentToPosition(idx);
_dgItems.Refresh();}

EDIT --------------------------------- This is the easier approach but I still need help with the lambda / filter expression and method call

// this is where I try to get the index of an object for highlighting
private void HandleUpdateListEvent(Object myobject)
AdrTypeMdl theNewItem = myobject as AdrTypeMdl;
var e = ItemsLcv.SourceCollection.GetEnumerator();

ItemsLcv.Filter = o => (o == theNewItem);
foreach (row in ItemsLcv)
{  if row == theNewItem
return e >;
e = -1;}
ItemsLcv.MoveCurrentToPosition(e);
ItemsLcv.Refresh();}

END EDIT ---------------------

In debugger I can see the class Objects in _dgItems. If I do this, it works.

        var idx = _dgItems.IndexOf(_dgItems[2]);

But the IndexOf method does not work when the parameter is just a class Object. I think the problem is with my cast of the DataGrid items to an ItemCollection. I need to cast the class Object, ie. myobject, to something recognizable by the ItemCollection that I got from the DataGrid. Is there a workaround? Thank you.

harpagornis
  • 103
  • 3
  • 17

1 Answers1

0

Try this.

You need to cast it to the type of collection ie AdrTypeMdl. You cannot simply get the index by passing an object. You're binding to a source ItemsLcv which is of type AdrTypeMd1. So pass that exact type to get the exact index.

var dgcolumn = myobject as AdrTypeMdl;
if(dgcolumn != null)
{
    var idx = _dgItems.IndexOf(dgcolumn);
}

idx will be the index of that corresponding column.

ViVi
  • 4,339
  • 8
  • 29
  • 52
  • Yes, I tried that and even an explicit declaration, below, but still get -1 for idx. AdrTypeMdl theNewItem = payload as AdrTypeMdl. – harpagornis Aug 20 '16 at 15:28
  • I mean entire code, so that I could try to reproduce the issue. – ViVi Aug 20 '16 at 18:11
  • It is a Prism Unity App & it will take a long time to scale down to just those working parts. – harpagornis Aug 20 '16 at 21:01
  • I think the approach is to add a filter method to ItemsLcv. Since it is a CollectionView and is bound two-way to the DataGrid's ItemCollection, I can just get the index I am looking for by iterating through CollectionView with an enumerator. Then I can update Currentitem in the CollectionView, and the DataGrid will automatically update also. I need help with implementing the lambda / filter method and method call. How do I modify the new code I added to the question? – harpagornis Aug 22 '16 at 14:01
  • I am sorry. But I can't understand your code posted above. try `foreach(var item in ItemsLcv) { //if some condition is met var idx = _dgItems.IndexOf(item); }` – ViVi Aug 22 '16 at 16:18
  • Thank you. I think I may need to also type cast the object for comparison. – harpagornis Aug 23 '16 at 02:40
  • Yes of course. Cast it to the proper type. In your case `AdrTypeMdl` – ViVi Aug 23 '16 at 02:57
  • Thank you for you help. I will mark it answer. I guess the DataGrid does not strongly type or cast its ItemCollection which explains why the IndexOf was not working. – harpagornis Aug 23 '16 at 03:30