0

I have an ObservableCollection bound to a DataGrid and everything works fine. I want to filter the collection without going to the database repeatedly so I decided to use a backing collection to store the original list and then publicly expose the filtered list to the binding. So I have the following code:

_backingMemberList.Clear();
_memberList.Clear();

foreach (Member CurrentMember in ListOfMembers)
{
    _memberList.Add(CurrentMember);
    _backingMemberList.Add(CurrentMember);
}

_memberList = new ObservableCollection<Member>(_backingMemberList);

and the binding is simply:

<DataGrid Name="dataGridMembers" ItemsSource="{Binding MemberList}" />

Now, for some reason this breaks the RowStyle

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
        <Setter Property="Background">
            <Setter.Value>
                <SolidColorBrush Color="{Binding BindsDirectlyToSource=True, Converter={StaticResource BGColor}}"/>                                
            </Setter.Value>
        </Setter>
    </Style>
</DataGrid.RowStyle>

I don't get any information on the output pane about the binding being right or wrong. I can't figure out what I'm doing wrong.

And just to add to the fun I've got the same hookup on an other page and it breaks the binding altogether. The rows don't even show.

My questions are:

  1. What am I doing wrong?
  2. Failing that, how do I debug a data binding?
Adi Lester
  • 24,731
  • 12
  • 95
  • 110
Tom Padilla
  • 924
  • 10
  • 30

1 Answers1

1

If could be this line that is causing your problems:

_memberList = new ObservableCollection<Member>(_backingMemberList);

by the looks of things you are overwriting the field (_memberList) which is presumably used by your property MemberList...with a different object instance...but the Binding is probably referring to the originally created one.....(your _memberList in the first half of the code is one instance....and then at the end of the code you set a new instance)...yes you are creating a shallow copy of the _backingMemberList...however you have changed _memberList...and need to tell the Binding to use the new instance of the collection.

You need to do an OnPropertyChanged("MemberList") to tell it that you changed the property....OR just don't do the "new"...as you already added the items to the collection by doing Clear() and Add() in your foreach.


Also going back to your explanation of why you are doing what you are doing...you might consider a different way to filter your collection.

Instead of making a copy, you could use a Filter on the CollectionViewSource which gets generated by WPF when your ItemsSource is bound to a collection. It sits between your ObservableCollection and the DataGrid.

Community
  • 1
  • 1
Colin Smith
  • 12,375
  • 4
  • 39
  • 47
  • That line doesn't overwrite the backing field, it initializes the new collection with a "shallow" copy of the backing collection. As for using the CollectionViewSource I found it to be more annoying than making a backing collection... unless, of course, the backing collection idea doesn't work. :) – Tom Padilla Aug 11 '12 at 20:47
  • OK, I tried using the CollectionViewSource and was not able to get it to work either. BUT when I Snoop the datagrid then the data shows up. This is the main reason I stopped trying to use it. – Tom Padilla Aug 11 '12 at 22:32
  • Did you try getting rid of the "new" statement, or firing the OnPropertyChanged? – Colin Smith Aug 11 '12 at 22:44
  • I tried removing the new and just adding to the collection and it works. But I think you are right, I should be using the mechanisms that are already in place to do this. So now I'm going to lookup how to use the CollectionViewSource and see if I can't figure out why it's not working the way it's supposed to for me. Thanks for the help and thanks for pointing me in the right direction. I'm going to mark this as the answer because the answer is to do it "the right way" and use the CollectionViewSource. – Tom Padilla Aug 12 '12 at 17:37