Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Silverlight Application with WCF Service and Child Windows as Popups - Part 2

0.00/5 (No votes)
13 May 2011 2  
Meeting Schedule - Part II - Saving to database and sending email to all the contacts

Introduction 

In Part 1, we had completed the following tasks:

  1. Creating and designing of Main page and Child window page using XAML
  2. Creating WCF service
  3. Consuming WCF service in Silverlight application
  4. Fetching data from database using WCF service
  5. Show data in the datagrid of popup child window of main page

Tasks for Part 2

In this part, the main working areas are as follows:

  1. Check Box Problems
  2. Adding the selected contacts of child window to Read only Contact Text Box
  3. Saving the Meeting Schedule into the database
  4. Sending email to all the selected contacts for meeting information

Check Box Problem

The main problem with check boxes is that of datagrid header check box. Providing they are all checked and all unchecked from header check box to the end user was a very challenging job initially, but later it becomes easy stuff. Below is the coding for this problem. When header check box is checked, all checkboxes should check and corresponding data will be added to the list generics and when unchecked none of the corresponding data is added to the list generics.

Add the following namespace for including observableCollection.

using System.Collections.ObjectModel;

Next two observableCollection type variables are defined in globally, having class type as their type.

public class newcontacts
{
    public string Fname { get; set; }
    public string Lname { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
}
ObservableCollection<newcontacts> allcontacts = new ObservableCollection<newcontacts>();
ObservableCollection<newcontacts> contactlist = new ObservableCollection<newcontacts>();

The below method is used to check all if header checkbox is checked.

/// <summary>
/// header check box on click method
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>

private void CheckBX_Click(object sender, RoutedEventArgs e)
{
    IsLoopNeeded = false;
    chk_header = sender as CheckBox;
    bool check = chk_header.IsChecked.Value;

    if (check)
    {
        foreach (newcontacts selectContacts in allcontacts)
        {
            chk_header = (CheckBox)dataGrid1.Columns[4].GetCellContent(selectContacts);
            if (chk_header.IsChecked != true)
            {
                chk_header.IsChecked = true;
            }
        }
        //In this case all contacts will be returned, 
        //so no need to change in allContacts list.
        IsContactPresent = true;
    }
    else
    {
        foreach (newcontacts selectContacts in allcontacts)
        {
            chk_header = (CheckBox)dataGrid1.Columns[4].GetCellContent(selectContacts);
            if (chk_header.IsChecked != false)
            {
                chk_header.IsChecked = false;
            }
        }
        //In this case no Contact will be returned, so either initialize a bool variable 
        //to false or empty allContacts list. First option looks good :)
        IsContactPresent = false;
    }
}

If individual check boxes are checked, then the following method is used in which recorded is added to list when check box is checked or removed when checkbox is unchecked.

void cell_chk_Click(object sender, RoutedEventArgs e)
{
    CheckBox chk = sender as CheckBox;
    bool check = chk.IsChecked.Value;
    IsLoopNeeded = true;
    newcontacts contacts = chk.DataContext as newcontacts;
    if (check)
    {
        if (!contactlist.Contains(contacts))
        {
            contactlist.Add(contacts);
        }
    }
    else
    {
         contactlist.Remove(contacts);
    }
}

Adding Selected Contacts from Child Window to Main Page Text Box

This is the most tricky part of this application and consumes most of the time. I had no idea how to add records to other pages which are checked. I had tried so many ways and logic, but those are not as good as this one. I think this is very good and fast as compared to others by using Delegate and EventHandler. Records from child window will be added only when clicked on ok button, not cancel or closing windows.

But to this task, I have used the paramertized consturctor. Using main class constructor for doing this is much faster than the above mentioned two methods. So below is the coding how this can be achieved.

Main Page Code Lines

Create private string type static variable for storing contacts which we get from child window.

 private static String Contacts = "";

Now create constructor of main class which gets the contacts from child window and is saved in static variable. All the methods and variables defined in the main page default constructor should be included in this construct. This is also important.

/// <summary>
/// Parametrized constructor
/// </summary> Created by Balwant
/// <param name="contactlist"></param>
public MainPage(string contactlist)
{
    InitializeComponent();
    Contacts = contactlist;
    this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    timeStart.ValueChanged +=
    new RoutedPropertyChangedEventHandler<DateTime?>(timeStart_ValueChanged);
}
//Popup myPopUp;
/// <summary>
/// Default Constructor
/// </summary>
public MainPage()
{
    InitializeComponent();
    this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    timeStart.ValueChanged +=
    new RoutedPropertyChangedEventHandler<DateTime?>(timeStart_ValueChanged);
} 

Now on closing of popup window(child window), add all those contacts to the read only text box for contacts.

/// <summary>
/// Show pop up on this button click
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, RoutedEventArgs e)
{
    Popup  myPopUp = new Popup();
    myPopUp.Show();
    myPopUp.Closed += new EventHandler(myPopUp_Closed);
}
/// <summary>
/// pop up close event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void myPopUp_Closed(object sender, EventArgs e)
{
    txtContacts.Text = Contacts;
    // throw new NotImplementedException();
} 

Child Window Code

Now in the child window CS code file, we have to send all selected contacts to the main page when ok button is clicked.

//These bool type variable is use to get the checkboxes status.
bool IsLoopNeeded = false;
bool IsContactPresent = true;
CheckBox chk_header;
private String _returnContactList = "";
public String returnContactList
{
    get
    {
        return _returnContactList;
    }
    set
    {
        _returnContactList = value;
    }
}

On Child window close event, the following code is executed:

void Popup_Closed(object sender, EventArgs e)
{
    if (this.DialogResult.Value == true)
    {
        if (IsLoopNeeded == false && IsContactPresent == true)
        {
            //*Please insert less then sign instead of $ for loops
            for (int i = 0;i $ allcontacts.Count; i++)
            {
                _returnContactList += allcontacts[i].Email.ToString() + ";";
            }
        }
        else if (IsLoopNeeded == false && IsContactPresent == false)
        {
            _returnContactList = "";
        }        
        else if (IsLoopNeeded == true)
        {
            //foreach (var contact in contactlist)
            //{
            //    chk_header = (CheckBox)dataGrid1.Columns[4].GetCellContent(contact);
            //if (chk_header.IsChecked == true)
            //{
            for(int i=0;i $ contactlist.Count;i++)
                _returnContactList += contactlist[i].Fname.ToString() + ";";
            //    }
          //}
        }
        //main page constructor is called here.
        MainPage obj = new MainPage(returnContactList);
    } 
    //   throw new NotImplementedException();
}

The following screen shot shows data retrieved from child window shows in read only text box.

Saving Meeting Information into Database and Sending Mail

Now we can used WCF service again to save the data in to database. Below is the WCF code for saving records and main page code to call WCF methods.

[OperationContract]
public string saveSchedule(string agenda, string location, 
	DateTime StartTime, DateTime EndTime, string contacts, string details)
{
    SqlConnection con = new SqlConnection();
    con.ConnectionString = WebConfigurationManager.ConnectionStrings
			["ConnectionString"].ConnectionString;
    SqlCommand cmd = new SqlCommand();
    con.Open();
    cmd.Connection = con;
    cmd.CommandText = "insert into Meeting values
	(@Title,@Location,@StartTime,@EndTime,@Contact,@Details,@CreatedDate)";
    cmd.Parameters.AddWithValue("@Title", agenda);
    cmd.Parameters.AddWithValue("@Location", location);
    cmd.Parameters.AddWithValue("@StartTime", StartTime);
    cmd.Parameters.AddWithValue("@EndTime", EndTime);
    cmd.Parameters.AddWithValue("@Contact", contacts);
    cmd.Parameters.AddWithValue("@Details", details);
    cmd.Parameters.AddWithValue("@CreatedDate", System.DateTime.Now);
    cmd.ExecuteNonQuery();
    return "Record is saved successfully, Thanks for submitting schedule for meeting.";
}
/// <summary>
/// This method is used to send email to all selected contacts 
///regarding meeting schedule.
/// </summary> By Balwant
/// <param name="agenda"></param>
/// <param name="Location"></param>
/// <param name="contacts"></param>
/// <param name="details"></param>
/// <returns></returns>
[OperationContract]
public string sendmail(string agenda, string Location, string contacts, string details)
{
    try
    {
         SmtpClient smtpClient = new SmtpClient();
         MailMessage objMail = new MailMessage();
         MailAddress objMail_fromAddress= new MailAddress("bablu909@gmail.com");
         MailAddress objMail_toAddress= new MailAddress(contacts);
         objMail.IsBodyHtml=true;
         objMail.From=objMail_fromAddress;
         objMail.To.Add(objMail_toAddress);
         objMail.Subject=agenda+"<br>";
         objMail.Body=" "+ details + " Location:-" +Location+ "";
         objMail.Priority=MailPriority.High;
         smtpClient.Credentials= new System.Net.NetworkCredential
				("bablu909@gmail.com","123balwant");
         smtpClient.EnableSsl=true;
         smtpClient.Send(objMail);
         return "An Email is send to all recipients for the meeting schedule";
     }
     catch (Exception ex)
     {
         return "Error Sending Email Please Try again" +ex;
     }
}

The main page code for calling WCF methods in main page and passing parameters.

private void btSchedule_Click(object sender, RoutedEventArgs e)
{
    DateTime start = Convert.ToDateTime(dateStart.Text +" " + 
			timeStart.Value.Value.TimeOfDay);
    DateTime end = Convert.ToDateTime(dateEnd.Text +" " + timeEnd.Value.Value.TimeOfDay);
    ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
    client.saveScheduleAsync
    (txtAgenda.Text,txtLocation.Text,start,end,txtContacts.Text,txtDetails.Text);
    client.saveScheduleCompleted +=
    new EventHandler<saveScheduleCompletedEventArgs>(client_saveScheduleCompleted);
    client.sendmailAsync(txtAgenda.Text,txtLocation.Text,
			txtContacts.Text,txtDetails.Text);
    client.sendmailCompleted +=
    new EventHandler<sendmailCompletedEventArgs>(client_sendmailCompleted);
}
void client_saveScheduleCompleted(object sender, saveScheduleCompletedEventArgs e)
{
    lblMessage.Content = e.Result;
    //throw new NotImplementedException();
}
void client_sendmailCompleted(object sender, sendmailCompletedEventArgs e)
{
    lblMessage.Content += e.Result;
    //throw new NotImplementedException();
}

Note

The complete source code and database script for this application can be found in the download link. Please inform me if you find that changing or any type of updating is required for this article or for the previous article. This article is complete only if you read Part 1.

Thanks and please provide feedback so that I can improve the quality and post more articles.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here