• ComboBox Databinding in WPF
    2 replies, posted
I have 4 comboboxes that contain 2 sets of data pulled from an xml document. The 1st and 3rd boxes are the main "category" while the 2nd and 4th are the "subcategory". When the 1st or 3rd selection is changed, the 2nd and 4th need to be updated with the corresponding data from the parent box. So far I have this: [code] <Window x:Class="wpf.wnd" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="543" Width="543"> <StackPanel> <StackPanel.Resources> <XmlDataProvider x:Key="MyData" Source="http://site.com/data.xml"/> </StackPanel.Resources> <TextBlock HorizontalAlignment="Center" FontWeight="Bold" Text="City"/> <ComboBox Height="23" Name="combo1" Width="120" ItemsSource="{Binding Source={StaticResource MyData}, XPath=//category1/parent/@name}" /> <TextBlock HorizontalAlignment="Center" FontWeight="Bold" Text="County"/> <ComboBox Height="23" Name="combo2" Width="120" ItemsSource="{Binding Source={StaticResource MyData}, XPath=//category1/parent/child/@name}"/> <TextBlock HorizontalAlignment="Center" FontWeight="Bold" Text="Cat"/> <ComboBox Height="23" Name="combo3" Width="120" ItemsSource="{Binding Source={StaticResource MyData}, XPath=//category2/parent/@name}"/> <TextBlock HorizontalAlignment="Center" FontWeight="Bold" Text="SubCat"/> <ComboBox Height="23" Name="combo4" Width="120" ItemsSource="{Binding Source={StaticResource MyData}, XPath=//category2/parent/child/@name}"/> </StackPanel> </Window> [/code] The xml would look like this: [code] <?xml version="1.0" ?> <Root> <category1> <parent name="cat1:p1"/> <parent name="cat1:p2"/> <parent name="cat1:p3"> <child name="cat1:p3:c1"/> </parent> </category1> <category2> <parent name="cat2:p1"/> <parent name="cat2:p2"/> <parent name="cat2:p3"> <child name="cat2:p3:c1"/> </parent> </category2> </Root> [/code] For example, combo1 is filled with "cat1:p1", "cat1:p2" and "cat1:p3". When p1 or p2 are selected, combo2 stays empty, but when p3 is selected, combo2 is autofilled with "cat1:p3:c1", same for combo3 and combo4. Ideally i'd like to do this all in xaml but if I have to do some code behind, whatever. Any other tips would be cool too. I just started with WPF. Just remembered, in the xml they also have a "url" attribute so if possible, can assign the entire node to a selection and in the code behind pull that node/url from the currently selected item? [b]Edit:[/b] I don't know if there's a more elegant way to do this, but I figured it out. No fancy layout or anything, just the skeleton. [code] <StackPanel> <StackPanel.Resources> <XmlDataProvider x:Key="MyData" Source="http://site.com/data.xml"/> </StackPanel.Resources> <TextBlock HorizontalAlignment="Center" FontWeight="Bold" Text="Combo1"/> <ComboBox Height="23" Name="combo1" Width="245" ItemsSource="{Binding Source={StaticResource MyData}, XPath=//category1/parent}"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding XPath=@name}"/> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> <TextBlock HorizontalAlignment="Center" FontWeight="Bold" Text="Combo2"/> <ComboBox Height="23" Name="combo2" Width="245" DataContext="{Binding ElementName=combo1, Path=SelectedItem}" ItemsSource="{Binding XPath=./child/@name}"/> <TextBlock HorizontalAlignment="Center" FontWeight="Bold" Text="Combo3"/> <ComboBox Height="23" Name="combo3" Width="245" ItemsSource="{Binding Source={StaticResource MyData}, XPath=//category2/parent}"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding XPath=@name}"/> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> <TextBlock HorizontalAlignment="Center" FontWeight="Bold" Text="Combo4"/> <ComboBox Height="23" Name="combo4" Width="245" DataContext="{Binding ElementName=combo3, Path=SelectedItem}" ItemsSource="{Binding XPath=./child/@name}"/> </StackPanel> [/code] [code] ItemsSource="{Binding Source={StaticResource MyData}, XPath=//category1/parent}"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding XPath=@name}"/> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> [/code] That sets the ItemsSource fr the combobox to pull from the stackpanel resource set above and to fill it with all the nodes from category1. The ItemTemplate defines how the items in the combobox will be displayed, here they are just going to be a textblock who's Text property is set to the name attribute of the current node. [code] <TextBlock HorizontalAlignment="Center" FontWeight="Bold" Text="Combo2"/> <ComboBox Height="23" Name="combo2" Width="245" DataContext="{Binding ElementName=combo1, Path=SelectedItem}" ItemsSource="{Binding XPath=./child/@name}"/> [/code] Combo2 is a bit easier. It sets it's datacontext as the above "parent" datasource, which here is the currently selected item in combo1, while the data made available is actually the entire node. The ItemsSource property is set to pull the child name from the current node. To pull a url, just use "./{parent|child}/@url.
Hello - This works great. However I tried to extend the XAML to include 3 combobox's with the 3rd populated based on the selection of the second. I can't seem to get it to work. The 1st 2 combobox's populate properly. The third is always empty. Can anyone help? below is my XAML and XML file: <ComboBox Margin="0,0,10,0" Name="combo1" Grid.Row="1" Grid.Column="1" TabIndex="0" FontFamily="Verdana" FontSize="12" Height="20" VerticalAlignment="Top" ItemsSource="{Binding Source={StaticResource MyData}, XPath=//Catagory/Class}"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding XPath=@name}"/> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> <ComboBox Margin="0,0,10,0" Name="combo2" Grid.Row="2" Grid.Column="1" TabIndex="0" FontFamily="Verdana" FontSize="12" Height="20" VerticalAlignment="Top" DataContext="{Binding ElementName=combo1, Path=SelectedItem}" ItemsSource="{Binding XPath=./SubDocumentType/@name}"> </ComboBox> <ComboBox Margin="0,0,10,0" Name="combo3" Grid.Row="3" Grid.Column="1" TabIndex="0" FontFamily="Verdana" FontSize="12" Height="20" VerticalAlignment="Top" DataContext="{Binding ElementName=combo2, Path=SelectedItem}" ItemsSource="{Binding XPath=./SubDocumentType/DocumentType/@name}"> </ComboBox> <?xml version="1.0" ?> <Root> <Catagory> <Class name="NonStandard"> <SubDocumentType name="Class1"> <DocumentType name="Non-STD - Abbey"/> <DocumentType name="Non-STD - Back"/> </SubDocumentType> <SubDocumentType name="Class2"> <DocumentType name="Non-STD - DirectDebit"/> <DocumentType name="Non-STD - Letter"/> </SubDocumentType> <SubDocumentType name="Class19"> <DocumentType name="Non-STD - LifeInsurance"/> <DocumentType name="Non-STD - Manu"/> <DocumentType name="Non-STD - SpringDirect"/> </SubDocumentType> </Class> <Class name="Standard"> <SubDocumentType name="All"> <DocumentType name="STD: AccidentRepairFormN"/> <DocumentType name="STD: AccountDetailsLetter"/> <DocumentType name="STD: BancTecDirectDeposit"/> <DocumentType name="STD: ManUCreditcard"/> <DocumentType name="STD: Ml_DocLifeIns"/> </SubDocumentType> </Class> <Class name="Correspondence"> <SubDocumentType name="Adjust Account"> <DocumentType name="W0101"/> <DocumentType name="W0102"/> <DocumentType name="W0103"/> <DocumentType name="W0104"/> </SubDocumentType> <SubDocumentType name="Benefit Adjustment"> <DocumentType name="W0201"/> <DocumentType name="W0202"/> <DocumentType name="W0203"/> <DocumentType name="W0204"/> </SubDocumentType> </Class> </Catagory> </Root>
bump an old thread again and I'll chop ya nob off Welcome to FP
Sorry, you need to Log In to post a reply to this thread.