locked
datagridcombobox with different itemssource per row RRS feed

  • Question

  • I would like to have a datagrid with a datagridcombobox in a column where the itemssource for the datagridcombobox varies with each row of the datagrid.  For example, I'd like 1 row in the datagrid where the items in the combobox column are football team names and in the next row the items in the combobox column are baseball team names.  Is this possible?
    Thursday, February 16, 2012 6:31 PM

Answers

  • I have recently answered another question with an example of combobox binding, which I have adapted to show you how you would do this.

    Start a new WPF project and paste this in:

    MainWindow.xaml

    <Window x:Class="WpfApplication16.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow"
            mc:Ignorable="d" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" >
    
        <Grid>
    
            <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Sports}" CanUserAddRows="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding SportName}"/>
                    <DataGridComboBoxColumn SelectedValueBinding="{Binding SelectedOption, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="OptionId" DisplayMemberPath="TeamName" >
                        <DataGridComboBoxColumn.ElementStyle>
                            <Style TargetType="ComboBox">
                                <Setter Property="ItemsSource" Value="{Binding Options}"/>
                            </Style>
                        </DataGridComboBoxColumn.ElementStyle>
                        <DataGridComboBoxColumn.EditingElementStyle>
                            <Style TargetType="ComboBox">
                                <Setter Property="ItemsSource" Value="{Binding Options}"/>
                            </Style>
                        </DataGridComboBoxColumn.EditingElementStyle>
                    </DataGridComboBoxColumn>
    
                </DataGrid.Columns>
            </DataGrid>
    
        </Grid>
    </Window>

    MainWindow.xaml.cs


    using System.Windows;
    using System.ComponentModel;
    using System.Collections.Generic;
    
    namespace WpfApplication16
    {
        public partial class MainWindow : Window
        {
            public class DbOption
            {
                public int OptionId { get; set; }
                public string TeamName { get; set; }
            }
    
            public class SportSelection : INotifyPropertyChanged
            {
                public string SportName { get; set; }
    
                int _selectedOption;
                public int SelectedOption
                {
                    get
                    {
                        return _selectedOption;
                    }
                    set
                    {
                        if (_selectedOption != value)   //  <--- put breakpoint here to prove it is updating source
                        {
                            _selectedOption = value;
                        }
                    }
                }
    
                public List<DbOption> Options { get; set; }
    
                void OnPropertyChanged(string prop)
                {
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs(prop));
                }
                public event PropertyChangedEventHandler PropertyChanged;
    
            }
    
            public List<SportSelection> Sports { get; set; }
    
            public MainWindow()
            {
                Sports = new List<SportSelection>
                {
                    new SportSelection { SportName="Football", Options = new List<DbOption> { new DbOption { TeamName = "Team A", OptionId=1}, new DbOption{TeamName="Losers", OptionId=2} }},
                    new SportSelection { SportName="Baseball", SelectedOption =2, Options = new List<DbOption> { new DbOption { TeamName = "Team 1", OptionId=1}, new DbOption{TeamName="Team 2", OptionId=2} }},
                };
    
                DataContext = this;
            }
        }
    }

    Regards,
    Pete


    #PEJL



    • Edited by Pete LakerMVP Thursday, February 16, 2012 7:42 PM
    • Marked as answer by re4 Wednesday, February 22, 2012 5:18 PM
    Thursday, February 16, 2012 7:39 PM

All replies

  • I have recently answered another question with an example of combobox binding, which I have adapted to show you how you would do this.

    Start a new WPF project and paste this in:

    MainWindow.xaml

    <Window x:Class="WpfApplication16.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow"
            mc:Ignorable="d" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" >
    
        <Grid>
    
            <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Sports}" CanUserAddRows="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding SportName}"/>
                    <DataGridComboBoxColumn SelectedValueBinding="{Binding SelectedOption, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="OptionId" DisplayMemberPath="TeamName" >
                        <DataGridComboBoxColumn.ElementStyle>
                            <Style TargetType="ComboBox">
                                <Setter Property="ItemsSource" Value="{Binding Options}"/>
                            </Style>
                        </DataGridComboBoxColumn.ElementStyle>
                        <DataGridComboBoxColumn.EditingElementStyle>
                            <Style TargetType="ComboBox">
                                <Setter Property="ItemsSource" Value="{Binding Options}"/>
                            </Style>
                        </DataGridComboBoxColumn.EditingElementStyle>
                    </DataGridComboBoxColumn>
    
                </DataGrid.Columns>
            </DataGrid>
    
        </Grid>
    </Window>

    MainWindow.xaml.cs


    using System.Windows;
    using System.ComponentModel;
    using System.Collections.Generic;
    
    namespace WpfApplication16
    {
        public partial class MainWindow : Window
        {
            public class DbOption
            {
                public int OptionId { get; set; }
                public string TeamName { get; set; }
            }
    
            public class SportSelection : INotifyPropertyChanged
            {
                public string SportName { get; set; }
    
                int _selectedOption;
                public int SelectedOption
                {
                    get
                    {
                        return _selectedOption;
                    }
                    set
                    {
                        if (_selectedOption != value)   //  <--- put breakpoint here to prove it is updating source
                        {
                            _selectedOption = value;
                        }
                    }
                }
    
                public List<DbOption> Options { get; set; }
    
                void OnPropertyChanged(string prop)
                {
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs(prop));
                }
                public event PropertyChangedEventHandler PropertyChanged;
    
            }
    
            public List<SportSelection> Sports { get; set; }
    
            public MainWindow()
            {
                Sports = new List<SportSelection>
                {
                    new SportSelection { SportName="Football", Options = new List<DbOption> { new DbOption { TeamName = "Team A", OptionId=1}, new DbOption{TeamName="Losers", OptionId=2} }},
                    new SportSelection { SportName="Baseball", SelectedOption =2, Options = new List<DbOption> { new DbOption { TeamName = "Team 1", OptionId=1}, new DbOption{TeamName="Team 2", OptionId=2} }},
                };
    
                DataContext = this;
            }
        }
    }

    Regards,
    Pete


    #PEJL



    • Edited by Pete LakerMVP Thursday, February 16, 2012 7:42 PM
    • Marked as answer by re4 Wednesday, February 22, 2012 5:18 PM
    Thursday, February 16, 2012 7:39 PM
  • Hi re4,

    Yes, another approach is StaticResource, you could refer to below sample:

    <Window.Resources>
            <loacl:Customers  x:Key="items"/>
        </Window.Resources>
    <StackPanel>
        <DataGrid Name="datagrid" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridComboBoxColumn Header="Combobox" DisplayMemberPath="FirstName " ItemsSource="{Binding Source={StaticResource items}}"/>
            </DataGrid.Columns>
        </DataGrid>
    </StackPanel>

    http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemssource(VS.95).aspx

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, February 21, 2012 8:21 AM
  • Thank you, Sheldon.  I tried the code on the link http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemssource(VS.95).aspx.  I cut and pasted each example into VS 2010.  I also used the XAML that you provided above to create a datagridcomboboxcolumn.  I was not able to get the desired effect.  I do not see how I can get 2 rows in a datagrid where the datagridcomboboxcolumn has different items per row.  I was able to get his effect using the code provided by "XAML guy", so I do have a solution.  But I am always curious if another solution exists.

    Could you please post a more complete solution that uses a StaticResource to achieve the desired effect?  You can cut and paste the code "XAML guy" supplied to see exactly what the desired effect is.

    Again, thank you (and "XAML guy") for your help. 

    Wednesday, February 22, 2012 5:50 PM