I have a problem with XAML databound controls and dataview filtering

Posted on 2014-08-27
Last Modified: 2014-09-09
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
  Message=Value cannot be null.
Parameter name: 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...

        <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}}"/>

<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" 
		ItemsSource="{Binding Source={StaticResource paceGrpsViewSource}}"
		SelectedValue="{Binding PaceGrp}" />

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();
            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();
            paceGrpsViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("paceGrpsViewSource")));

        private void ApplyFilter()
                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;

Open in new window

Question by:MikeDFarrant

    Author Comment

    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.


    Accepted Solution

    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.

    Author Closing Comment

    My solution works but it does not explain what I had done wrong, if anything.

    Featured Post

    IT, Stop Being Called Into Every Meeting

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Join & Write a Comment

    Suggested Solutions

    Title # Comments Views Activity
    Email Body 4 32
    Change to event 1 50
    report c# 9 60
    (code works) but print excel in Landscape 3 10
    In my previous article ( we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
    A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
    Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
    Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

    746 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    15 Experts available now in Live!

    Get 1:1 Help Now