0

I currently have a C# WPF .NET 4.5 application. I am using a DataGrid to show items from the project's database. I am able to populate everything in the DataGrid except for the DataGridComboBoxColumn. First, i would just like to get it to display data. In the future, I would like the combobox to display on the first line the current value in the database, but have the ComboBox contain set values, to limit what users can enter. SO it would be like list item1 = current value, list item2 = pounds, list item3 = ounces, etc. The Table has 3 columns I am working with, InventoryName, Qty, and Type. Type should be the ComboBox

Here is my Code

 private AuroraDataEntities auroraDataEntities;
     public ViewCup()
    {            
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        LoadData();
    }

    private void LoadData()
    {
        auroraDataEntities = new AuroraDataEntities();
        dgInv.DataContext = auroraDataEntities.Inventories;
    }

   void EditComplete(object sender, SelectedCellsChangedEventArgs e)
    {
        auroraDataEntities.SaveChanges();
    }

    private void Window_Unloaded(object sender, RoutedEventArgs e)
    {
        auroraDataEntities.SaveChanges();
    }


  }

And here is my XAML

        <DataGrid x:Name="dgInv" HorizontalAlignment="Center" Height="134" Margin="-10,96,10,0" VerticalAlignment="Top" Width="Auto" 
              IsSynchronizedWithCurrentItem="True" 
              ItemsSource="{Binding}" 
              AutoGenerateColumns="False"  
              GridLinesVisibility="None" 
              SelectedCellsChanged="EditComplete">
        <DataGrid.Columns>
            <DataGridTextColumn Width="200" Header="InventoryName" Binding="{Binding InventoryName}" />
            <DataGridTextColumn Width="50" Header="Qty" Binding="{Binding Qty}" />
            <DataGridComboBoxColumn x:Name="cbType"
                                    Width="50" 
                                    Header="Type" 
                                    ItemsSource="{Binding Path=Type, Mode=TwoWay}" 
                                    DisplayMemberPath="Type" 
                                    SelectedValueBinding="{Binding Type}" >     
            </DataGridComboBoxColumn>
        </DataGrid.Columns>
    </DataGrid>
Joe K
  • 231
  • 7
  • 16

2 Answers2

1

In order to get the DataGridComboBoxColumn to work correctly, you have to use the ElementStyle and EditingElementStyle as follows:

<DataGridComboBoxColumn x:Name="cbType" Width="50" Header="Type" 
    DisplayMemberPath="Type" SelectedValueBinding="{Binding Type}" >
    <DataGridComboBoxColumn.ElementStyle>
        <Style TargetType="{x:Type ComboBox}">
            <Setter Property="ItemsSource" Value="{Binding Type}"/>
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style TargetType="{x:Type ComboBox}">
            <Setter Property="ItemsSource" Value="{Binding Type}"/>
        </Style>
    </DataGridComboBoxColumn.ElemEditingElementStyleentStyle>
</DataGridComboBoxColumn>

This will populate the ComboBox in the grid column with your ItemsSource. Depending on how you're using the ComboBox in the grid, you may not need to set the ElementStyle. See this answer for some information on why this is necessary.

Community
  • 1
  • 1
Brian S
  • 5,675
  • 1
  • 22
  • 22
  • Tried what you suggested, Combo Box is still not populating. – Joe K Aug 04 '13 at 18:15
  • What\Where is the Type property that you're binding your `ItemsSource` to? As @Akash indicates above, you'll need some object as your `DataContext` that has all the necessary properties for binding. – Brian S Aug 05 '13 at 14:36
0

Your DataContext should have a ViewModel which should expose two separate properties, Inventories and TypeCollection (an array or list containing ounces, pounds etc) and you should bind ItemsSource of DataGridComboBoxColumn to TypeCollection and SelectedValueBinding to Type.

public class ViewModel{

    // implement INotifyPropertyChanged for following
    public IEnumerable TypeCollection{ get; private set;}

    public IEnumerable Inventories {get; private set;}

}

// set DataContext as shown below

 this.DataContext = new ViewModel(.....);

// Set Binding as shown below

    <DataGrid x:Name="dgInv" HorizontalAlignment="Center" Height="134" Margin="-10,96,10,0" VerticalAlignment="Top" Width="Auto" 
          IsSynchronizedWithCurrentItem="True" 
          ItemsSource="{Binding Inventories}" 
          AutoGenerateColumns="False"  
          GridLinesVisibility="None" 
          SelectedCellsChanged="EditComplete">
    <DataGrid.Columns>
        <DataGridTextColumn Width="200" Header="InventoryName" Binding="{Binding InventoryName}" />
        <DataGridTextColumn Width="50" Header="Qty" Binding="{Binding Qty}" />
        <DataGridComboBoxColumn x:Name="cbType"
                                Width="50" 
                                Header="Type" 
                                ItemsSource="{Binding Path=DataContext.TypeCollection,
    RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}}" 
                                DisplayMemberPath="Type" 
                                SelectedValueBinding="{Binding Path=Type, Mode=TwoWay}" >     
        </DataGridComboBoxColumn>
    </DataGrid.Columns>
</DataGrid>

Note that you have to use RelativeSource to find DataContext of parent DataGrid.

Akash Kava
  • 39,066
  • 20
  • 121
  • 167