4
votes

I have a Data Grid With a text column and a Combo Box Column.

The Data Grid Columns is as Follows:

<DataGrid.Columns>
    <DataGridTextColumn Header="ID"  
                        Binding="{Binding ID}" 
                        Width="0.5*" />
    <DataGridComboBoxColumn Header="Threshold"  
                            x:Name="Threshold" 
                            SelectedItemBinding="{SelectedValue}"/>
</DataGrid.Columns>

For the ComboBox Column I am using a List as an ItemSource.

Threshold.ItemsSource = MaxThreshold; //MaxThreshold is a List

So every row has a ComboBox which consists of the List values.

The user selects a particular row and then selects the combo box in that particular row. I want to get the value of the item selected in the ComboBox in c#.

Thanks.

2
Do you follow MVVM concept? I.e., do you have class that represents Item in your DataGrid?VMaleev
I do have a class for the items in my DataGrid. I then make a List of them and provide it as an ItemSource to the ComboBoxAbhishek
So, you have SelectedValue property in your class, correct? Why cannot you take SelectedItem or SelectedItems of your DataGrid, cast it to your type and then take SelectedValue from it?VMaleev

2 Answers

5
votes

To do the job you want you first need a data model, that is, in your case this model must contain two properties, and this model implements the INotifyPropertyChanged interface to notify the UI that property values They have changed. Below is the model that fits in your example, I called the model MyModel:

public class MyModel: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private object _id;
        public object ID 
        {
            get { return _id; }
            set 
            { 
                _id = value;
                this.OnPropertyChanged(new PropertyChangedEventArgs("ID"));
            }
        }

        private object _selectedItem;
        public object SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                this.OnPropertyChanged(new PropertyChangedEventArgs("SelectedItem"));
            }
        }

        public virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, e);
        }
    }

Note: You must change the type of attributes and properties for the type it deems necessary.

Your DataGrid would be something like the XAML shown below (the properties that fill the DataGrid and the ComboBox are in the .cs file of the window):

<DataGrid x:Name="myDataGrid" AutoGenerateColumns="False" 
                  ItemsSource="{Binding MyDataGridItems,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}">
            <DataGrid.Columns >
                <DataGridTextColumn Header="   ID"  
                        Binding="{Binding ID}" 
                        Width="0.5*" />
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox x:Name="Threshold" 
                                      SelectedItem="{Binding SelectedItem, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                      ItemsSource="{Binding MaxThreshold,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

In Window .cs file we have the following code snippet:

 public List<MyModel> MyDataGridItems { get; set; }
 public List<object> MaxThreshold { get; set; }

In the constructor of Window you can initialize the lists:

myDataGridItems = new List<MyModel>()
{
      new MyModel(){ID=1},
      new MyModel(){ID=2},
      new MyModel(){ID=3},
      new MyModel(){ID=4},
      new MyModel(){ID=5},
};

MaxThreshold = new List<object>()
{
    "Item 1",
    "Item 2",
    "Item 3",
    "Item 4",
    "Item 5"
};

And to pick up the selected item of combobox in the particular row of DataGrid you can iterate through the items of the DataGrid, or access the desired row directly, is an example:

//iterate rows
foreach(MyModel model in myDataGrid.Items)
{
    var selecteditem = model.SelectedItem;//here you have selected item
}

//access directly
var model = myDataGrid.Items[0] as MyModel;
if(model!=null)
   var selecteditem = model.SelectedItem;//here you have selected item
0
votes

Here is my exemple:

XAML code:

<DataGrid.Columns>
  <DataGridTextColumn Binding="{Binding FeatureName}" />
  <DataGridCheckBoxColumn  Binding="{Binding FeatureExists}" />
  <DataGridComboBoxColumn DisplayMemberPath="MachineID" SelectedItemBinding="{Binding SelectedMchn}">
     <DataGridComboBoxColumn.ElementStyle>
        <Style>
          <Setter Property="ComboBox.ItemsSource" Value="{Binding Path=FeatureMachines}" />
        </Style>
     </DataGridComboBoxColumn.ElementStyle>
     <DataGridComboBoxColumn.EditingElementStyle>
        <Style>
           <Setter Property="ComboBox.ItemsSource" Value="{Binding Path=FeatureMachines}" />
        </Style>
      </DataGridComboBoxColumn.EditingElementStyle>
   </DataGridComboBoxColumn>                                

in code behind I have my property:

private ObservableCollection<DGFeature> _BarDetail;
    public ObservableCollection<DGFeature> BarDetail
    {
        get { return _BarDetail; }
        set
        {
            if (_BarDetail != value)
            {
                _BarDetail = value;
                OnPropertyChanged("BarDetail");
            }
        }
    }

I have created a class for populating the datagrid:

  public class DGFeature
{
    public string FeatureName { get; set; }
    public bool FeatureExists { get; set; }
    public List<LibTrackingSystem.Machine> FeatureMachines { get; set; }
    public LibTrackingSystem.Machine SelectedMchn { get; set; }
    public DGFeature()
    {
        FeatureMachines = new List<LibTrackingSystem.Machine>();
        SelectedMchn = new LibTrackingSystem.Machine();
    }
}

SelectedMchn is used to set the selected item in the combo box