Smaug
Smaug

Reputation: 2673

How can I define dependency binding in Datagrid

I've defined the below XAML. The binding populated the DataGridComboBoxColumn, If I choose the PartNumber in the combobox at the same time another property (PartName) value needs to be bind in the DataGridTextColumn. How could I do that binding in DataGridTextColumn ?

<Window.Resources>
  <ObjectDataProvider x:Key="RecordValues"
                      ObjectType="{x:Type local:RecordTemp}"
                      MethodName="GetPersonList">
  </ObjectDataProvider>
</Window.Resources>
<Grid>
  <Grid>
    <DataGrid AutoGenerateColumns="False"
              ItemsSource="{Binding}"
              Margin="10"
              Name="dataGrid1">
      <DataGrid.Columns>
        <DataGridComboBoxColumn Header="Combo"
                                Width="300"
                                SelectedItemBinding="{Binding Values}"
                                DisplayMemberPath="PartNumber"
                                ItemsSource="{Binding Source={StaticResource RecordValues}}" />
        <DataGridTextColumn Header="Order Name"
                            Binding="" />
      </DataGrid.Columns>
    </DataGrid>
  </Grid>
</Grid>

In C# defined below code,

    ObservableCollection<RecordTemp> RecordsTemp = new ObservableCollection<RecordTemp>();

    RecordsTemp.Add(new RecordTemp());
    RecordsTemp.Add(new RecordTemp());
    dataGrid1.DataContext = RecordsTemp;  


   public class RecordTemp
    {
    List<PartsList> _value = new List<PartsList>();

       public RecordTemp()
    {
        _value.Add(new PartsList() { PartName = "One", PartNumber = "1", PartQuantity = 20 });
        _value.Add(new PartsList() { PartName = "Two", PartNumber = "2", PartQuantity = 10 });
    }

    public List<PartsList> value
    {
        get { return _value; }
        set { _value = value; }
    }

    public List<PartsList> GetPersonList()
    {
        return _value;
    }
    }

public class PartsList
    {
        public string PartName { get; set; }
        public double PartQuantity { get; set; }
        public string PartNumber { get; set; }
    }

Upvotes: 0

Views: 117

Answers (1)

Anand Murali
Anand Murali

Reputation: 4109

One way to accomplish this is to

  1. Add a new property (say the property name is SelectedPart) in RecordTemp class which will store the selected PartList obj.

  2. Bind SelectedPart property to the SelectedValue property of the ComboBox.

  3. Bind SelectedPart to the text box.

  4. Now, RecordTemp class should implement INotifyPropertyChanged interface so that the UI is updated when the user changes the ComboBox value.

Here are the modifications that I had done to your code.

<DataGrid AutoGenerateColumns="False"
          ItemsSource="{Binding}"
          Margin="10"
          Name="dataGrid1"
          CanUserAddRows="False">
  <DataGrid.Columns>
    <DataGridTemplateColumn Header="Combo">
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <ComboBox SelectedValue="{Binding SelectedPart, UpdateSourceTrigger=PropertyChanged}"
                    DisplayMemberPath="PartNumber"
                    ItemsSource="{Binding Source={StaticResource RecordValues}}" />
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTextColumn Header="Order Name"
                        Binding="{Binding SelectedPart.PartName}" />
  </DataGrid.Columns>
</DataGrid>

Code behind file. You might have to change the namespace.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ObservableCollection<RecordTemp> RecordsTemp = new ObservableCollection<RecordTemp>();

            RecordsTemp.Add(new RecordTemp());
            RecordsTemp.Add(new RecordTemp());
            dataGrid1.DataContext = RecordsTemp;
        }
    }

    public class RecordTemp : INotifyPropertyChanged
    {
        List<PartsList> _value = new List<PartsList>();

        public RecordTemp()
        {
            _value.Add(new PartsList() { PartName = "One", PartNumber = "1", PartQuantity = 20 });
            _value.Add(new PartsList() { PartName = "Two", PartNumber = "2", PartQuantity = 10 });
        }

        public List<PartsList> value
        {
            get { return _value; }
            set { _value = value; }
        }

        private PartsList _SelectedPart;

        public PartsList SelectedPart
        {
            get { return _SelectedPart; }
            set
            {
                _SelectedPart = value;
                OnPropertyChanged("SelectedPart");
            }
        }

        public List<PartsList> GetPersonList()
        {
            return _value;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    public class PartsList
    {
        public string PartName { get; set; }
        public double PartQuantity { get; set; }
        public string PartNumber { get; set; }
    }
}

Upvotes: 1

Related Questions