Solved

ComboBox Multibinding with ObjectDataProvider

Posted on 2010-08-26
8
1,969 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
 

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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 500 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

This article shows a few slightly more advanced techniques for Windows 7 gadget programming, including how to save and restore user settings for your gadget and how to populate the "details" panel that is displayed in the Windows 7 gadget gallery.  …
This article describes how to programmatically preset the "Pages per Sheet" option that's available with most printer drivers.   This setting lets you do "n-Up" printing, where two, four, or more pages are printed on each sheet of paper. If your …
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…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

929 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

14 Experts available now in Live!

Get 1:1 Help Now