I have a problem with XAML databound controls and dataview filtering

I have a couple of data tables, one holds a list of songs with one of the fields being PaceGrp.  This points to another table which holds the descriptions of all the pace groups.

I have setup in Xaml as shown below and use a bound combobox to maintain the pacegrp field so the user sees just the description but the correct value is set in the songs table.

This works perfectly well until I decide to apply a filter to the songs data table.  When a filter is in place so that only some of the pace groups are visible in the dataview, if I then use the combobox to select a pace group outside of the those available in the filtered data I get an unhandled error (which doesn't take me to a line to help me debug)...


System.ArgumentNullException was unhandled
  HResult=-2147467261
  Message=Value cannot be null.
Parameter name: key
  Source=mscorlib
  ParamName=key
....

I'm guessing I'm probably binding the data incorrectly in Xaml, but I'm not sure...  here are some code extracts which shows what I'm doing....
BTW the try - catch in the ApplyFilter section doesn't catch the error.

Thanks in advance...

XAML:
   
 <Window.Resources>
        <local:dsSongs x:Key="dsSongs"/>
        <CollectionViewSource x:Name="dvMainData" x:Key="mainDataViewSource" Source="{Binding MainData, Source={StaticResource dsSongs}}" />
        <CollectionViewSource x:Key="paceGrpsViewSource" Source="{Binding PaceGrps, Source={StaticResource dsSongs}}"/>

 </Window.Resources>
...
<DockPanel x:Name="SongPanel" HorizontalAlignment="Left" Width="588" Background="SteelBlue"  DataContext="
{StaticResource mainDataViewSource}"
...
    <ComboBox Grid.Row="0" Grid.Column="3" Grid.RowSpan="2" Height="23" 
		x:Name="ComboBox1" Width="177" Margin="2"  HorizontalAlignment="Left" 
		IsEditable="False"
		ItemsSource="{Binding Source={StaticResource paceGrpsViewSource}}"
		DisplayMemberPath="Description"
		SelectedValuePath="PaceGrp" 
		SelectedValue="{Binding PaceGrp}" />
...
</DockPanel>

Open in new window

c# code:
        csEnlight_WPF.dsSongs dsSongs;
        csEnlight_WPF.dsSongsTableAdapters.MainDataTableAdapter dsSongsMainDataTableAdapter;
        CollectionViewSource mainDataViewSource;
        csEnlight_WPF.dsSongsTableAdapters.PaceGrpsTableAdapter dsSongsPaceGrpsTableAdapter;
        CollectionViewSource paceGrpsViewSource;
        DataView dvGrid;
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            dsSongs = ((csEnlight_WPF.dsSongs)(this.FindResource("dsSongs")));
            // Load data into the table MainData. You can modify this code as needed.
            dsSongsMainDataTableAdapter = new csEnlight_WPF.dsSongsTableAdapters.MainDataTableAdapter();
            dsSongsMainDataTableAdapter.Fill(dsSongs.MainData);
            mainDataViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("mainDataViewSource")));
            dvGrid = dsSongs.MainData.DefaultView;

            // Load data into the table PaceGrps. You can modify this code as needed.
            dsSongsPaceGrpsTableAdapter = new csEnlight_WPF.dsSongsTableAdapters.PaceGrpsTableAdapter();
            dsSongsPaceGrpsTableAdapter.Fill(dsSongs.PaceGrps);
            paceGrpsViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("paceGrpsViewSource")));
            ApplyFilter();
}



        private void ApplyFilter()
        {
            try
            {
                string PaceGroupString = null;

                if (FilterFast.IsChecked)
                    PaceGroupString += " or PaceGrp = '" + FilterFast.Tag + "'";
                if (FilterMedF.IsChecked)
                    PaceGroupString += " or PaceGrp = '" + FilterMedF.Tag + "'";
                if (FilterMedS.IsChecked)
                    PaceGroupString += " or PaceGrp = '" + FilterMedS.Tag + "'";
                if (FilterSlow.IsChecked)
                    PaceGroupString += " or PaceGrp = '" + FilterSlow.Tag + "'";
                if (FilterChrs.IsChecked)
                    PaceGroupString += " or PaceGrp = '" + FilterChrs.Tag + "'";
                if (FilterOths.IsChecked)
                    PaceGroupString += " or PaceGrp > '4'";
                filterString = PaceGroupString.Substring(4, PaceGroupString.Length - 4);
                dvGrid.RowFilter = filterString;
            }
            catch
            {
            }
        }

Open in new window

MikeDFarrantAsked:
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.

MikeDFarrantAuthor Commented:
I'm still struggling with this... grrr...  perhaps the only solution is to unbind the combobox and handle the refreshes and updates in the code behind (not really my preference).
If anyone has had this problem and found a solution or perhaps is also still struggling like me please share with me.

Thanks
0
MikeDFarrantAuthor Commented:
So... no takers to help me out :(

Here's what I found just in case anyone else has found a similar problem:

I had bound two controls to my database (a Slider control and a combobox control) which caused my database to crash if I moved either of the values in these controls outside of the filter I had in place for the current view.

So for example I had a Slider relating to song rating which could be any value from 1 to 5.   I filtered my data view down to show just songs with a rating of 3 or greater.   Viewing my grid I notice that one song has a rating of 3 but really it's not that good so I want to move the slider down to 2 (outside of the range currently in view).   I expected to be able to change the slider position and as soon as I finished moving the slider, the song would just disappear from the view.   Instead I got an exception...

Similar filters on text boxes worked ok - so if I had a filter showing all songs containing the word 'girl' in the title and I changed one of the songs so the title did not contain that word, I did not get an exception - the song simply disappeared from the list as expected.

So because of that fact I was able to create a work-around:
This was to unbind the slider and combobox from the data table and created hidden textboxs instead which were bound to the data.   I then put some code in the slider after value changed and combobox after selection changed which manually updated the bound text boxes with the new values.   As if by magic, everything worked again...

My VB.NET winforms version of this program (I'm re-writing and upgrading) worked without the work-around...

If anyone reading this could provide some sort of explanation why this happens I'd be really interested to learn.
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
MikeDFarrantAuthor Commented:
My solution works but it does not explain what I had done wrong, if anything.
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
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.