Wednesday, November 4, 2009

Data binding to combobox inside DataGrid



Data binding to combobox inside DataGrid in Silverlight


Step 1:

Create a class to bind with data grid
public class patient : INotifyPropertyChanged
{
   public string fName{get;set;}
   public string lName{get;set;}
   public string patientAccount{get;set;}
   private string AppointmentStatus;
   public string appointmentStatus
   {
    get { return AppointmentStatus; }
    set
    {
     AppointmentStatus = value;
     if (PropertyChanged != null)
      { 
PropertyChanged(this, new PropertyChangedEventArgs("AppointmentStatus"));
       }
    }
}
//constructor 
public patient(string fName,string lName,string patientAccount,string appointmentStatus)
 {
    this.fName=fName;
    this.lName=lName;
    this.patientAccount=patientAccount;
    this.appointmentStatus = appointmentStatus;
 }
    public event PropertyChangedEventHandler PropertyChanged;
}

NOTE:

InotifyPropertyChanged is implemented inside System.ComponentModel NameSpace
This is a simple class that holds the element for one row of data grid. There are three text and one combo box. I will bind the combobox to reflect the change in patient class.
This class also implements the InotifyPropertyChanged to give an event on the change of a property. We can fire this on every property change or one property as desired.
Now we have to create a class that will hold all the rows of datagrid. Above class only present one row of datagrid.
We can do this
List<patient> patientList=new List();
Or we can create our own class that implements the collection model.
public class patients : ObservableCollection
{
 public patients()
 {
  patient p = new patient("Mamoon", "ur Rasheed", "1010100", "Cleared");
  p.PropertyChanged += new PropertyChangedEventHandler(p_PropertyChanged);
  this.Add(p);
  p = new patient("Ahmed", "Jamsheed", "1010200", "Rescheduled");
  p.PropertyChanged += new PropertyChangedEventHandler(p_PropertyChanged);
  this.Add(p);
  p = new patient("Nisar", "Ali", "1010300", "Cancelled");
  p.PropertyChanged += new PropertyChangedEventHandler(p_PropertyChanged);
 this.Add(p); 
}
void p_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
   patient p=(patient)sender;
   MessageBox.Show("First Name: "+p.fName+"\nLast Name: "+p.lName+"\nPatient Account: "+p.patientAccount+"\nAppointment Status: "+p.appointmentStatus);
}
}

NOTE:

ObservableCollection is defined in System.Collections.ObjectModel NameSpace

This class implements the ObservableCollection to make it a collection class. Detail is simple, in constructor I am adding three patients details and alos binding to propertyChanged event


Step 2:

Defining the combobox items
public class appointmentStatus : ObservableCollection
    {
        public appointmentStatus()
        {
            this.Add("Cancelled");
            this.Add("Cleared");
            this.Add("Rescheduled");
        }
    }
This class also implements the ObservableCollection to make it a collection class and in the constructor, it adds three items.

Now I will create a class that will be called directly to get the appointment status for combobox.

    public class appointmentStatusList
    {
        public appointmentStatus appStatus
        {
            get{
                return new appointmentStatus();
            }
            set{
                this.appStatus=value;
            }
        }
    }
This class did nothing special other than returning the appointment status list. This will be used to bind the combobox inside datagrid.


Step 3:

C# code behind file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightApplication
{
    public partial class MainPage : UserControl
    {
        patients p;
        public MainPage()
        {
            InitializeComponent();
            p = new patients();
            datagrid1_bindData();
        }
        private void datagrid1_bindData()
        {
            //patients p = new patients();
            dataGrid1.ItemsSource = p;
           
        }
        private void displayValue()
        {
            foreach (patient pat in p)
            {
                MessageBox.Show(pat.appointmentStatus);
            }
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            displayValue();
        }
    }
}

This above code will first initilize the patients class new object and then assign it to datagrid1 as itemsource.

Step 4:

There are three important steps:
1-  Add the namespace of your application as highligted below in XAML. In my case it is silverlightapplication
2-  Add the appointmentStatusList class as the resource of user control as highlighted in second number in the following XAML
3-  Define the datagrid columns
a.  3 text columns
b.  1 combobox

  


As you see datagrid1 itemsource property was set in code behind file. In this above XAML, datagrid members are defined to bind with the properties that are in patient.
Combobox is a difficult thing to bind when inside datagrid.First if you will recall I wrote in description of patient class that appointmentstatus is added to selecte the default value of combobox. Appointment status holds the value that you wish to be selected by default.

ItemsSource="{Binding appStatus,Source={StaticResource appointmentStatusList}}"  />

SelectedItem is bound with appointmentStatus that will used to select the value inside appointmentStatusList.
ItemSource property is bound in different way, there are two major part. First is
Source={StaticResource appointmentStatusList}
That is actually the part that we have to define in our XAML and I have already described them at the start.
Second
{Binding appStatus}
Which is the property of appointmentStatusList class. What happen here is, For each combobox inside the datagrid, a new instance of appointmentStatusList will be created and its default value will be selected by using the selectedItem binding property.

Binding Mode:

I have binded the combobox selectedItem property in TwoWay mode. There are three modes
1-  OneTime ( Bind once )
2-  OneWay (Bind once and it can change the value of associated property but not object)
3-  TwoWay (with this mode, change will get reflected to the object)
When you will run this program, and you will change the appointment status, you will see a message box that will show the change property that gets reflected in object.
I hope this article will help.

Download:

http://rapidshare.com/files/302472648/silverlight_combobox_inside_datagrid_binding.zip

No comments:

Post a Comment