Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

ComboBox Multibinding with ObjectDataProvider

Posted on 2010-08-26
8
Medium Priority
?
2,072 Views
Last Modified: 2013-11-12
I have 2 cmobo boxes - one a list of countries, and another a list of counties in that country. Both ItemsSources are bound to ObjectDataProviders and a multibinding on the country combo box SelectedValue sets a MethodParameter for the counties itemssource to filter the counties list.

This works fine when manually selecting a country in the combo, but when initially populating through binding the 0 value specified in the MethodParmeters (I am just using this as a default value for when no country is selected) is passed and no counties are returned.  The correct value is selected in the country combo box on load and the multibinding is working, but it seems the counties ObjectDataProvider is not updating when a new MethodParameter is specified.

Any ideas how to fix this?

 
<ObjectDataProvider x:Key="Countries"
                            ObjectType="{x:Type common:HCRCountry}"
                            MethodName="getCountryAll" />
        <ObjectDataProvider x:Key="Counties"
                            ObjectType="{x:Type common:HCRCounty}"
                            MethodName="getCountiesByCountry">
            <ObjectDataProvider.MethodParameters>
                <system:Int32>0</system:Int32>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

<ComboBox Name="cboCountry"
                  Grid.Column="3"
                  Grid.Row="2"
                  Margin="5,2"
                  ItemsSource="{Binding Source={StaticResource Countries}}"
                  DisplayMemberPath="CountryName"
                  SelectedValuePath="CountryID">
                <ComboBox.SelectedValue>
                    <MultiBinding Converter="{StaticResource MultiConv}"  >
                        <Binding Path="CountryID" 
                                 Converter="{StaticResource IDConv}" 
                                 UpdateSourceTrigger="PropertyChanged" />
                        <Binding Source="{StaticResource Counties}"    
                                 Path="MethodParameters[0]"    
                                 BindsDirectlyToSource="True"
                                 Converter="{StaticResource IDConv}"
                                 Mode="OneWayToSource"/>
                    </MultiBinding>
                </ComboBox.SelectedValue>
            </ComboBox>

Open in new window

0
Comment
Question by:Phil_Larby
  • 4
  • 4
8 Comments
 
LVL 29

Expert Comment

by:Gautham Janardhan
ID: 33652932
Cant tell why it's not working for you without the rest of the code.. Any way take a look at the code posted here (basically your code here + i filled in the rest of the stuff). This is working as per your requirement
0
 
LVL 29

Expert Comment

by:Gautham Janardhan
ID: 33652934
converters , HCRCountry and HCRCounty
public class HCRCountry
    {
        public string CountryName { get; set; }
        public int CountryID { get; set; }
        public List<HCRCountry> getCountryAll()
        {
            return new List<HCRCountry>()
            {
                new HCRCountry()
                {
                    CountryID = 1,
                    CountryName = "India1"
                },
                new HCRCountry()
                {
                    CountryID = 2,
                    CountryName = "India2"
                },
                new HCRCountry()
                {
                    CountryID = 3,
                    CountryName = "India3"
                },
                new HCRCountry()
                {
                    CountryID = 4,
                    CountryName = "India4"
                }
            };
        }
    }

    public class HCRCounty
    {
        public string CountyName { get; set; }
        public int CountyID { get; set; }
        public List<HCRCounty> getCountiesByCountry(int country)
        {
            return new List<HCRCounty>()
            {
                new HCRCounty()
                {
                    CountyName = "County for country" + country.ToString(),
                    CountyID = 1
                }
            };
        }

        public List<HCRCounty> getCountiesByCountry(object country)
        {
            return getCountiesByCountry((int)country);
        }
    }

    public class ConverterTemp : IMultiValueConverter, IValueConverter
    {
        #region IMultiValueConverter Members

        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (values != null && values.Length == 2 && (values[0] as HCRCountry) != null)
            {
                var temp = values[0] as HCRCountry;
                return temp.CountryID;
            }
            return 0;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            return new object[] { value, value };
        }

        #endregion

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;
        }

        #endregion
    }

Open in new window

0
 
LVL 29

Expert Comment

by:Gautham Janardhan
ID: 33652938
xaml
<Grid.Resources>
            <common:ConverterTemp x:Key="MultiConv" />
            <common:ConverterTemp x:Key="IDConv" />
            <ObjectDataProvider x:Key="Countries"
                            ObjectType="{x:Type common:HCRCountry}"
                            MethodName="getCountryAll" />
            <ObjectDataProvider x:Key="Counties"
                            ObjectType="{x:Type common:HCRCounty}"
                            MethodName="getCountiesByCountry">
                <ObjectDataProvider.MethodParameters>
                    <system:Int32>0</system:Int32>
                </ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>
        </Grid.Resources>
        <StackPanel>
            <ComboBox Name="cboCountry"
                  Grid.Column="3"
                  Grid.Row="2"
                  Margin="5,2"
                  ItemsSource="{Binding Source={StaticResource Countries}}"
                  DisplayMemberPath="CountryName"
                  SelectedValuePath="CountryID">
                <ComboBox.SelectedValue>
                    <MultiBinding Converter="{StaticResource MultiConv}"  >
                        <Binding Path="CountryID" 
                                 Converter="{StaticResource IDConv}" 
                                 UpdateSourceTrigger="PropertyChanged" />
                        <Binding Source="{StaticResource Counties}"    
                                 Path="MethodParameters[0]"    
                                 BindsDirectlyToSource="True"
                                 Converter="{StaticResource IDConv}"
                                 Mode="OneWayToSource"/>
                    </MultiBinding>
                </ComboBox.SelectedValue>
            </ComboBox>
            
            <ComboBox Name="cboCounty"
                  ItemsSource="{Binding Source={StaticResource Counties}}"
                  DisplayMemberPath="CountyName"
                  SelectedValuePath="CountyID">
            </ComboBox>

        </StackPanel>

Open in new window

0
Learn Veeam advantages over legacy backup

Every day, more and more legacy backup customers switch to Veeam. Technologies designed for the client-server era cannot restore any IT service running in the hybrid cloud within seconds. Learn top Veeam advantages over legacy backup and get Veeam for the price of your renewal

 

Author Comment

by:Phil_Larby
ID: 33655930
Thanks for taking a look at this, however I dont think this resolves the isse.  I had the dependent combo boxes working fine when manully selecting a country from the country combo.  

The problem I have is when the form is bound to a business object containing a countryID.  When teh data context is set, the correct country is selected in the country combo, but the ItemsSource of the counties combo never updates.


public class TestData: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public TestData()
        {
            CountryID = new Random().Next(1, 4);
            CountyID = 4;
        }

        int _countryID;
        public int CountryID
        {
            get { return _countryID; }
            set { _countryID = value; OnPropertyChanged("CountryID"); }
        }

        int _countyID;
        public int CountyID
        {
            get { return _countyID; }
            set { _countyID = value; OnPropertyChanged("CountyID"); }
        }

        public string ItemName
        {
            get {return "Item " + CountryID;}
            set { ;}
        }

        private void OnPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

    public class HCRCountry
    {
        public string CountryName { get; set; }
        public int CountryID { get; set; }
        public List<HCRCountry> getCountryAll()
        {
            return new List<HCRCountry>()
            {
                new HCRCountry()
                {
                    CountryID = 1,
                    CountryName = "India1"
                },
                new HCRCountry()
                {
                    CountryID = 2,
                    CountryName = "India2"
                },
                new HCRCountry()
                {
                    CountryID = 3,
                    CountryName = "India3"
                },
                new HCRCountry()
                {
                    CountryID = 4,
                    CountryName = "India4"
                }
            };
        }
    }

    public class HCRCounty
    {
        public string CountyName { get; set; }
        public int CountyID { get; set; }
        public List<HCRCounty> getCountiesByCountry(int country)
        {
            return new List<HCRCounty>()
            {
                new HCRCounty()
                {
                    CountyName = "County for country" + country.ToString(),
                    CountyID = 1
                }
            };
        }

        public List<HCRCounty> getCountiesByCountry(object country)
        {
            return getCountiesByCountry((int)country);
        }
    }

    public class ConverterTemp : IMultiValueConverter, IValueConverter
    {
        #region IMultiValueConverter Members

        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return values[0]; 
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            return new object[] { value, value };
        }

        #endregion

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;
        }

        #endregion
    }

Open in new window

0
 

Author Comment

by:Phil_Larby
ID: 33655933

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:common="clr-namespace:WpfApplication1"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" Height="350" Width="525">
    <Grid Name="grdDetails">
        <Grid.Resources>
            <common:ConverterTemp x:Key="MultiConv" />
            <common:ConverterTemp x:Key="IDConv" />
            <ObjectDataProvider x:Key="Countries"
                            ObjectType="{x:Type common:HCRCountry}"
                            MethodName="getCountryAll" />
            <ObjectDataProvider x:Key="Counties"
                            ObjectType="{x:Type common:HCRCounty}"
                            MethodName="getCountiesByCountry">
                <ObjectDataProvider.MethodParameters>
                    <system:Int32>0</system:Int32>
                </ObjectDataProvider.MethodParameters>
            </ObjectDataProvider>
        </Grid.Resources>
        <StackPanel>
            <TextBox Name="txtItem" 
                     Text="{Binding Path=ItemName}" />
            <ComboBox Name="cboCountry"
                  ItemsSource="{Binding Source={StaticResource Countries}}"
                  DisplayMemberPath="CountryName"
                  SelectedValuePath="CountryID">
                <ComboBox.SelectedValue>
                    <MultiBinding Converter="{StaticResource MultiConv}"  >
                        <Binding Path="CountryID" 
                                 UpdateSourceTrigger="PropertyChanged" />
                        <Binding Source="{StaticResource Counties}"    
                                 Path="MethodParameters[0]"    
                                 BindsDirectlyToSource="True"
                                 Mode="OneWayToSource"/>
                    </MultiBinding>
                </ComboBox.SelectedValue>
            </ComboBox>

            <ComboBox Name="cboCounty"
                  ItemsSource="{Binding Source={StaticResource Counties}}"
                  DisplayMemberPath="CountyName"
                  SelectedValuePath="CountyID">
            </ComboBox>
            
            <Button Name="btnNewItem" 
                    Content="New Item" 
                    Width="100" 
                    Margin="10" Click="btnNewItem_Click" />
        </StackPanel>

    </Grid>
</Window>

Open in new window

0
 

Author Comment

by:Phil_Larby
ID: 33655934

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            LoadNewDataItem();
        }

        private void btnNewItem_Click(object sender, RoutedEventArgs e)
        {
            LoadNewDataItem();
        }

        private void LoadNewDataItem()
        {
            grdDetails.DataContext = new TestData();
        }
    }
}

Open in new window

0
 
LVL 29

Accepted Solution

by:
Gautham Janardhan earned 2000 total points
ID: 33656114
i guess we need to add this line after LoadNewDataItem() in the ctr


            ((ObjectDataProvider)grdDetails.Resources["Counties"]).MethodParameters[0] = ((TestData)grdDetails.DataContext).CountryID;
0
 

Author Comment

by:Phil_Larby
ID: 33659908
Forcing the update in code like this does work, however it is not the clean solution I was hoping for.  I will continue to investigate reasons why the binding may not work - but will hapillly award you you the points if can't find a better solutions.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …

972 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