locked
Binding combobox itemsSource to other combobox selectedItem inside a listView RRS feed

  • Question

  • Hi,
    I'm trying to bind a itemsSource of a combobox to another combobox selectedItem. However both comboxes are actually inside a diffrent columnTemplates of a listView:

     

    <ListView ItemsSource="{Binding ConflictingActions}" Name="lvMain" SelectedIndex="{Binding SelectedIndex}" SelectedItem="{Binding SelectedItem}">  
                    <ListView.View> 
                        <GridView> 
                            <GridViewColumn Header="Issues">  
                                <GridViewColumn.CellTemplate> 
                                    <DataTemplate> 
                                        <ComboBox DisplayMemberPath="Issue.Name" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.FileTypeIssues}" x:Name="cbxIssues" SelectedIndex="{Binding Path=id}" SelectionChanged="RowUpdatedHandler"></ComboBox> 
                                    </DataTemplate> 
                                </GridViewColumn.CellTemplate> 
                            </GridViewColumn> 
                            <GridViewColumn Header="Resolutions">  
                                <GridViewColumn.CellTemplate> 
                                    <DataTemplate> 
                                        <ComboBox DisplayMemberPath="AllowedResolutions" ItemsSource="{Binding ElementName=cbxIssues, Path=SelectedItem.AllowedResolutions}" SelectedIndex="{Binding Path=id}"></ComboBox> 
                                    </DataTemplate> 
                                </GridViewColumn.CellTemplate> 
                            </GridViewColumn> 
                         </GridView> 
                    </ListView.View> 
                </ListView> 

    The code above does not work and the second combobox remains empty. I've also tried forking with findAncestor but (as you can see above it is not an ancestor I'm trying to get but rather a sibling.

    --
    Thank you,
    Ken

    Thursday, February 12, 2009 5:12 AM

All replies

  • Hi,

     

    Based on my understanding, the second ComboBox is out of the scope of the first one in you code.If you want to achieve the functionality such as mater-detail, you can use two master-detailed ComboBoxs with binding syntax to display hierarchical data source outside ListView. if in cases you want to display tabular datasource, you can use a ListView handily. In terms of the code you explained above, you use the syntax in one of the ComboBox like this:


    <
    ComboBox Width="80"

              Name="comboBoxFruitName"

              ItemsSource="{Binding Converter={StaticResource converter},RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" />


    This will make all the rows in ListView duplicate. So this code makes less sense.

     

    A small example:

    XAML code:

    <Window x:Class="WpfABindingTest.Window2"

       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

       xmlns:local="clr-namespace:WpfABindingTest"

       Title="BindingTest" Height="300" Width="318">

        <StackPanel>

            <ListView Name="listview" >

                <ListView.View>

                    <GridView>

                        <GridViewColumn Header="FruitName">

                            <GridViewColumn.CellTemplate>

                                <DataTemplate>

                                    <TextBlock Text="{Binding Path=FruitName}"  />

                                </DataTemplate>

                            </GridViewColumn.CellTemplate>

                        </GridViewColumn>

                        <GridViewColumn Header="FruitSeeds">

                            <GridViewColumn.CellTemplate>

                                <DataTemplate>

                                    <ComboBox x:Name="cbxFruitSeeds"

                                              Width="80"

                                              SelectedIndex="0"

                                              ItemsSource="{Binding Path=FruitSeeds}">

                                        <ComboBox.ItemTemplate>

                                            <DataTemplate>

                                                <StackPanel Orientation="Horizontal">

                                                    <TextBlock Text="{Binding Path=ID}"  />

                                                    <TextBlock Text=" " />

                                                    <TextBlock Text="{Binding Path=Name}"  />

                                                </StackPanel>

                                            </DataTemplate>

                                        </ComboBox.ItemTemplate>

                                    </ComboBox>

                                </DataTemplate>

                            </GridViewColumn.CellTemplate>

                        </GridViewColumn>

                    </GridView>

                </ListView.View>

            </ListView>

            <!--another approach-->

            <Grid Margin="5,10,5,10">

                <Grid.RowDefinitions>

                    <RowDefinition />

                    <RowDefinition />

                </Grid.RowDefinitions>

                <Grid.ColumnDefinitions>

                    <ColumnDefinition />

                    <ColumnDefinition />

                </Grid.ColumnDefinitions>

                <TextBlock Text="Fruits"  Grid.Row="0" Grid.Column="0" />

                <TextBlock Text="FruitSeeds"  Grid.Row="0" Grid.Column="1" />

                <ComboBox  Name="comboBoxFruits"

                           Grid.Row="1" Grid.Column="0"

                           DisplayMemberPath="FruitName" />

                <ComboBox  Name="comboBoxFruitSeeds"

                           Grid.Row="1" Grid.Column="1"

                           ItemsSource="{Binding ElementName=comboBoxFruits,Path=SelectedItem.FruitSeeds}"

                           DisplayMemberPath="Name" />

            </Grid>

        </StackPanel>

    </Window>

     

    In the code behind:

    using System.Collections.Generic;

    using System.Windows;

    using System.Windows.Documents;

    using System.Collections.ObjectModel;

    namespace WpfABindingTest

    {

        public partial class Window2 : Window

        {

            public Window2()

            {

                InitializeComponent();

                this.Loaded += delegate

                {

                    List<Fruit> FruitList = new List<Fruit>();

                    for (int i = 1; i < 10; i++)

                    {

                        FruitList.Add(new Fruit()

                        {

                            FruitName = "Fruit" + i.ToString(),

                            FruitSeeds = new ObservableCollection<FruitSeed>()

                        {

                            new FruitSeed() { ID = i.ToString(), Name = "FruitSeedName" + i.ToString()},

                            new FruitSeed() { ID = (i+1).ToString(), Name = "FruitSeedName" + (i+1).ToString()},

                            new FruitSeed() { ID = (i+2).ToString(), Name = "FruitSeedName" + (i+2).ToString()}

                        }

                        });

                    }

                    listview.ItemsSource = FruitList;

                    comboBoxFruits.ItemsSource = FruitList;

                };

            }

        }

        public class Fruit

        {

            private string fruitName;

            public string FruitName

            {

                get { return fruitName; }

                set

                {

                    fruitName = value;

                }

            }

            private ObservableCollection<FruitSeed> fruitSeeds;

            public ObservableCollection<FruitSeed> FruitSeeds

            {

                get { return fruitSeeds; }

                set

                {

                    fruitSeeds = value;

                }

            }

        }

        public class FruitSeed

        {

            public string ID { get; set; }

            public string Name { get; set; }

        }

    }

    Help this helps.

     

    Thanks.


    Jim Zhou -MSFT
    Tuesday, February 17, 2009 3:43 AM
  • Hi Jim,
    Thank you for your reply.
    Your exsample avoid seperating the comboboxes into diffrent columns. Is that on purpose? Is there no way to have the same functionality while each combobox is in a column of its own?
    Thank you,
    Ken
    Tuesday, February 17, 2009 8:20 PM
  • Hi,

     

    -->Your exsample avoid seperating the comboboxes into diffrent columns. Is that on purpose? Is there no way to have the same functionality while each combobox is in a column of its own?

     

    The code I provided above included two approaches to display the data source in the code behind. Can you demonstrate you requirements with a small ,complete and ready-to-run example more clearly?

     

    Thanks.


    Jim Zhou -MSFT
    Wednesday, February 18, 2009 8:45 AM
  • Hi Jim,
    I'll try to clarify. Basically I'm asking why XAML above does not work while the one below does. As you can see the only diffrerent is that in the one above I tried to use DataColumn while in the example below I gave up on them. In the original example above the second combobox doesn't get populated and in the exaple below it does. Can I make the original example work without giving up on the columns?

    <ListView ItemsSource="{Binding ConflictingActions}" Name="lvMain" SelectedIndex="{Binding SelectedIndex}" SelectedItem="{Binding SelectedItem}">     
                    <ListView.View>    
                        <GridView>    
                            <GridViewColumn>    
                                <GridViewColumn.Header>    
                                    <StackPanel  Style="{DynamicResource StackPanelHorizontal}">     
                                        <TextBlock Style="{DynamicResource TextBlockHeader}">Issue</TextBlock>    
                                        <TextBlock Style="{DynamicResource TextBlockHeader}">Resolution</TextBlock>    
                                        <TextBlock Style="{DynamicResource TextBlockHeader}">Action</TextBlock>    
                                    </StackPanel>    
                                </GridViewColumn.Header>    
                                    <GridViewColumn.CellTemplate>    
                                    <DataTemplate>    
                                        <StackPanel>    
                                            <ComboBox DisplayMemberPath="Issue.Name" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.FileTypeIssues}" SelectedItem="{Binding FileTypeIssue}" x:Name="cbxIssues"></ComboBox>    
                                            <ComboBox DisplayMemberPath="Resolution.Name" ItemsSource="{Binding ElementName=cbxIssues, Path=SelectedItem.AllowedResolutions}"  SelectedValue="{Binding Resolution.Id}" SelectedValuePath="@Resolution.Id"></ComboBox>    
                                            <ComboBox DisplayMemberPath="Name" ItemsSource="{Binding ElementName=cbxIssues, Path=SelectedItem.Actions}" SelectedItem="{Binding Action}"></ComboBox>    
                                        </StackPanel>    
                                    </DataTemplate>    
                                </GridViewColumn.CellTemplate>    
                            </GridViewColumn>    
                        </GridView>    
                    </ListView.View>    
                </ListView>    
     

    Thank you,
    Ken
    Thursday, February 19, 2009 11:39 PM