Solved

ComboBox Multibinding with ObjectDataProvider

Posted on 2010-08-26
8
1,961 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:Phil_Larby
Comment Utility

<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
Comment Utility

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
Comment Utility
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
Comment Utility
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
This article surveys and compares options for encoding and decoding base64 data.  It includes source code in C++ as well as examples of how to use standard Windows API functions for these tasks. We'll look at the algorithms — how encoding and decodi…
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…
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…

744 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

11 Experts available now in Live!

Get 1:1 Help Now