Blog of a Filipino Developer about C#, VB.NET, ASP.NET, Java, PHP, SQL Server, MySql and Oracle RSS 2.0
# Wednesday, October 22, 2008

In part 3 of this 5 part series I am going to show you how to make a Master-Detail View in ASP.NET. I you weren't able to see the two previous post you can check them out here:

This post is a continuation of what we started in the two previous post wherein i show you how to consume a webservice ins ASP.NET and present the values returned by the service to the user in a much more meaninful way.

To start off with this post lets look at how the application from our last article look-liked:

As you can see, we have a textbox that accepts a user-input asking for the symbol to lookup in our webservice, a button that triggers that query event and a DetailsView that displays the returned resultset. This works great.

But what if I have a list of symbols that I want the user to see information regarding them? The answer is to show them in a master-detail view so that the user can get a clearer view of the information on each symbol.

To start with this demo lets begin by deleting everything that we have on the page. Yup! we are starting from scratch so that we can get a clearer picture on how we can build a master-detail view screen. Once everything is cleared on the page let's begin by adding a DataList control on our page with a Label control inside its ItemTemplate:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Keith Rull's Consuming Web Services Sample</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:DataList   ID="stockDataList" 
                            runat="server">
                <ItemTemplate>
                    <asp:Label  ID="quoteLabel" 
                                runat="server" 
                                Text='<%# Container.DataItem %>'>
                    </asp:Label>
                </ItemTemplate>
                <SeparatorTemplate>
                    <br />
                </SeparatorTemplate>
            </asp:DataList>
        </div>
    </form>
</body>
</html>

The first thing that you would notice on the code above is that we have assigned a value to the Text property of our Label control. This value signifies that we are binding the Container.DataItem value to the Text property. This DataItem will come from the value that we are going to set in the codebehind file for this page which in this case is just going to be a List<string>.

Next, lets go the codebehind file and create the Page_Load event for our page:

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            //create a list of stock symbols
            List<string> listOfSymbols = new List<string>();

            //add some symbols to our list
            listOfSymbols.Add("MSFT");
            listOfSymbols.Add("GOOG");
            listOfSymbols.Add("CSCO");
            listOfSymbols.Add("MER");
            listOfSymbols.Add("F");

            //bind the list<string> to our datalist
            stockDataList.DataSource = listOfSymbols;
            stockDataList.DataBind();
        }
    }
}

All i did in the code above is create a list of strings, add some values to it and assign and bind that colletion of strings to our DataList. Running the application now would give us this result:

Nothing really impressive yet. Now let's add the cool part wherein we call a web service and show the information for each stock symbol.

To do that we need to add another DataList inside the ItemTemplate of our first DataList. The second DataList will serve as the list that shows the imformation about the specified execution symbol. We also need to add an event that is triggered each time a ListItem is binded to a data. Below is our modified HTML page:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Keith Rull's Consuming Web Services Sample</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:DataList   ID="stockDataList" 
                            runat="server" 
                            OnItemDataBound="stockDataList_ItemDataBound">
                <ItemTemplate>
                    <asp:Label  ID="quoteLabel" 
                                runat="server" 
                                Text='<%# Container.DataItem %>'>
                    </asp:Label>
                    <asp:DataList   ID="stockInformationDataList" 
                                    runat="server">
                        <ItemTemplate>
                            <table  cellpadding="1" 
                                    cellspacing="1" 
                                    border="0" 
                                    width="600px">
                                <tr>
                                    <td><b>Last:</b>&nbsp;<%# Eval("Last") %></td>
                                    <td><b>Date:</b>&nbsp;<%# Eval("Date") %></td>
                                    <td><b>Time:</b>&nbsp;<%# Eval("Time") %></td>
                                    <td><b>Change:</b>&nbsp;<%# Eval("Change") %></td>
                                </tr>
                                <tr>
                                    <td><b>Open:</b>&nbsp;<%# Eval("Open") %></td>
                                    <td><b>Low:</b>&nbsp;<%# Eval("Low") %></td>
                                    <td><b>High:</b>&nbsp;<%# Eval("High") %></td>
                                    <td><b>Volume:</b>&nbsp;<%# Eval("Volume") %></td>
                                </tr>
                                <tr>
                                    <td><b>MktCap:</b>&nbsp;<%# Eval("MktCap") %></td>
                                    <td><b>PrvClose:</b>&nbsp;<%# Eval("PreviousClose") %></td>
                                    <td><b>PerChange:</b>&nbsp;<%# Eval("PercentageChange") %></td>
                                    <td><b>AnnRange:</b>&nbsp;<%# Eval("AnnRange") %></td>
                                </tr>
                                <tr>
                                    <td><b>Earns:</b>&nbsp;<%# Eval("Earns") %></td>
                                    <td><b>P-E:</b>&nbsp;<%# Eval("P-E") %></td>
                                    <td>&nbsp</td>
                                    <td>&nbsp</td>
                                </tr>
                            </table>
                        </ItemTemplate>
                    </asp:DataList>
                </ItemTemplate>
                <SeparatorTemplate>
                    <br />
                </SeparatorTemplate>
            </asp:DataList>
        </div>
    </form>
</body>
</html>

I modified the ItemTemplate of our second DataList () and added an html table to hold the values that the web service returns. This way the view that we are presenting is much more readable.

Next stop is looking at the code behind where all these magic is going to be wired. All the work for the detail view will happen on the stockDataList_ItemDataBound event and no further modification to our Page_Load event is needed. Let me show you the code for that event before I start explaining every bits and pieces of that code:

protected void stockDataList_ItemDataBound(object sender, DataListItemEventArgs e)
{
    //check whether the current listitem is an acceptable ListItemType
    if (e.Item.ItemType == ListItemType.Item
        || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        //get the binded symbol
        string symbol = e.Item.DataItem.ToString();

        //find the datalist in our itemtemplate
        Control foundControl = e.Item.FindControl("stockInformationDataList");
        //cast the control to a DataList
        DataList stockInformationDataList = (DataList)foundControl;
        //get the stock information for the specified symbol
        DataSet stockInformationDataSet = StockQuoteHelper.GetStockQuoteDataSet(symbol);

        //bind the dataset to our datalist
        stockInformationDataList.DataSource = stockInformationDataSet;
        stockInformationDataList.DataBind();
    }
}

What we are doing on this blog of code is we are checking if the ItemType of the current item being binded-to is either a ListItemType.Item or ListItemType.AlternatingItem. If it passes this criteria we then read the DataItem that was binded to this ListItem which in this case is our executionSymbol. The next step is to find our stockInformationDataList control and assign the stockInformationDataSet to it. The stockInformationDataSet contains the values that is retrieved from our stock web service by passing the exection symbol to our StockQuoteHelper.GetStockQuoteDataSet method.

Running our completed application will result to this screen:

And that's it! We've accomplished a master-detail view in ASP.NET. Pretty easy right? I hope you learned something from this tutorial. Next up we'll update this project and implement some Asynchronous Web Service calls via ASP.NET AJAX and show you some fun ways to present a master-detail view in a much more interesting way.

As always, source code is available for download here: KeithRull.ConsumingWebServices.Part3.zip (6.9 KB)

As a side note, many thanks to John A. Miller from Trofholz Technologies, Inc. for reminding me about this series. I totally forgot about it already after being assigned to a large project the past few months. Thanks John!

Wednesday, October 22, 2008 8:21:07 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET | AJAX | ASP.NET | Fun Stuff | Tutorial
# Tuesday, October 21, 2008

Whew! It's been a long time since the last time that we had a cool contest here at DevPinoy and I think it's about time to start giving away cool stuff those developers who are willing to take the challenge. This time around I've decided to make the contest a little bit more interesting than the usual...

Ok, enough with the teaser and on with the contest!

Our challenge this months is to build a Windows-based Bible application in  C#, VB.NET or Java. The idea is to build an application that reads from a Bible database and displays testaments, books, chapters and verses based on these simple requirements:

  1. The user should be able to search for books base on a selected Testament (Old and New).
  2. The user should be able to see the contents of each Book
  3. The user should be able to search the contents of the Bible based on different search criterias like "Luke", "Genesis 1", "John 3:16", "love", "Abraham" and the application should be able to return the matching results.
  4. The user should be able to jump from one book to another.
  5. The user should be able to jump from one chapter to another.

That is all that is required for the app and it's up to you to add additional functionalities if you like. You can find the database for this challenge here: http://devpinoy.org/media/p/30310.aspx

Simple right? Here's the caveat! You are not allowed to use any third-party library in your solution (Yup! No NHibernate or Hibernate for you buddy!). Everything should be straight up what your language of choice supports. The only acceptable third-party library is a testing and mocking framework as part of your test harness but this is not required.

So what's the prize? Glad you asked! We are going to chose 2 winners for this contest and they will be able to chose 1 of these lovely prizes courtesy of JetBrains: IntelliJ IDEA, ReSharper, Team City(one Build Agent), dotTrace and JetBrain's forthcoming Ruby IDE(they don't have a name for it yet).

So who is entitled to join this contest? This contest is open to all Filipino developers who are willing to take the challenge regardless of location and ofcourse you should be a member of the DevPinoy website.

So how can I participate? All you need to do is finish the application and send it to keith.rull@gmail.com together with the source code before October 26, 2008 PST. Please include "DevPinoy October 2008 Code Challenge" on the subject line of your email when submitting your code. Please also include a screenshot of your application and your fullname in your submission email.. All submissions would be posted on October 27, 2008 PST in my devpinoy blog so the community can view your work. The announcement of winners will take place on October 29, 2008 PST.

Ready for the challenge? Stop reading, start typing and send your solution as quick as you can!

Tuesday, October 21, 2008 9:36:18 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET | Contest | Fun Stuff | Java
# Tuesday, September 23, 2008

In part 1 of this series i showed you how to specify the voice, gender, rate and volume of the our SpeechSynthesizer object. This time i'm going to show you how to use predefined Voices in your machine and utilize it as hints to your SpeechSynthesizer object.

The first thing that I did to our sample project is change the UI since we would not need the Gender and Age combo box in our form. The result is a UI like this:

Next, we need to figure out a way to extract the names of the installed voices in our machine. To this we need to use the SpeechSynthesizer.GetInstalledVoices() method. This method, when invoked returns a readonly collection of TTS(text-to-speech) voices also known as InstalledVoice objects that are readily available in your machine. The InstalledVoice object contains a property called VoiceInfo which represents the voice information about that TTS voice. To begin our project we need to get all the VoiceInfo objects on each and every InstalledVoice. Below is a code snippet showing how we can accomplish this task:

//create a new speechsynthesizer object
static SpeechSynthesizer speechSynth = new SpeechSynthesizer();
/// <summary>
/// a method that returns all the currently installed voice
/// info objects in the machine
/// </summary>
/// <returns>a list of VoiceInfo objects</returns>
private static List<VoiceInfo> GetInstalledVoices()
{
    //get the current cultureinfo
    CultureInfo currentCulture = CultureInfo.CurrentCulture;

    //use linq to select each voiceinfo object from the intalledvoices collection
    var listOfVoiceInfo = from voice
                              in speechSynth.GetInstalledVoices(currentCulture)
                          select voice.VoiceInfo;

    //return the selected voiceinfo objects
    return listOfVoiceInfo.ToList<VoiceInfo>();
}

Next, we need to bind the resulting list to our voiceComboBox.

private void MainForm_Load(object sender, EventArgs e)
{
    BindData();
}

/// <summary>
/// Bind the voices to our combobox
/// </summary>
private void BindData()
{
    //get the installed voices
    List<VoiceInfo> listOfVoices = GetInstalledVoices();
    //bind the list to our combobox
    voicesComboBox.DataSource = listOfVoices;
    voicesComboBox.DisplayMember = "Name";
}

And finally we need to create the logic inside our button click event to initiate our SpeechSynthesizer

private void speakUpButton_Click(object sender, EventArgs e)
{
    //get the values specified in our form
    string messageToSay = wordsTextBox.Text;
    int selectedVolume = volumeTrackBar.Value;
    int selectedVoiceRate = voiceRateTrackBar.Value;

    //get the selected voice info
    VoiceInfo vi = voicesComboBox.SelectedItem as VoiceInfo;
                
    //specify the volume for our SpeechSynthesizer object
    speechSynth.Volume = selectedVolume;
    //specify the rate  for our SpeechSynthesizer object
    speechSynth.Rate = selectedVoiceRate;
    //specify the voice info specifying the voice to use
    speechSynth.SelectVoice(vi.Name);
    //say the message
    speechSynth.SpeakAsync(messageToSay);
}

And we are done ;) Running the application would show as all the installed TTS voice in our machine. One thing to note is that this list is machine dependent and different machines might contain different voices.

Clicking the "Speak!" button should echo our selected voice.

Next time I'll show you how to export the resulting speech to a wave file. HTH

Tuesday, September 23, 2008 8:54:03 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET | Fun Stuff | Tutorial
# Friday, September 19, 2008

Ever wondered how google would look like if it was on terminal mode (a la *Nix shell)? Then checkout Goosh! Goosh is a project that Stefhan Grothkopp started. The application behaves similar to a unix-shell wherein you type commands and it returns results based on your request (which in this case is web search results). I personally love the idea and have been using the tool since i found it.

This reminds me of the days when terminals were hip and cool. I do wish that the background was black though and the fonts converted to green to give more terminal-like feel to it but either way its two thumbs up for me ;)

Friday, September 19, 2008 12:20:01 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Fun Stuff
# Thursday, September 18, 2008

One of the cool things that came out with .NET 3.x is the addition of System.Speech library. This library is a collection of classes that enables you to do alot of speech related things like speech recognition and text-to-speech conversion. It's a handful to talk about so i suggest you read up MSDN to learn more about this library[1][2][3].

The app I'm going to show you today is a basic application that shows how to utilize the SpeechSynthesizer class that is located inside the System.Speech.Synthesis namespace.

To start this demo lets add a reference to the System.Speech namespace to our project. You can do this by doing a right-click on References > Add Reference and selecting System.Speech from the list.

Once added we can now beging utilizing this library by adding a using directive pointing to the specific System.Speech namepace that we want to utilize. For this demo we will use System.Speech.Synthesis

Next, we need to create a new SpeechSynthesizer object. SpeechSynthesizer is class that enables you to convert text-to-speech. The class also has several properties and methods that you can use customize the voice information on your speech synthesizer.

Next is the fun part which is making our application say some words. The cool thing about SpeechSynthersizer is that all you need to do to make your application speak is call the SpeechSynthesizer.Speak() method and your done ;)

Run our application and once started you should here the words "Hello, World" spoken by your machine. Pretty cool huh?!

What we did was a simple demonstration on how to make our apps speak with a few lines using SpeechSynthesizer. But what about customizing the voice? Fear not! I created a sample application that will show you how you can customize the synthesizer by specifying the rate, volume, gender and age of the emitted sound. Below is the screenshot showing the UI for the application

And here is the code snippet with comments detailing how to customize our SpeechSynthesizer object.

using System;
using System.Windows.Forms;
using System.Speech.Synthesis;

namespace KeithRull.TalkToMeGoose
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        //create a new speechsynthesizer object
        SpeechSynthesizer speechSynth = new SpeechSynthesizer();

        private void speakUpButton_Click(object sender, EventArgs e)
        {
            //get the values specified in our form
            string messageToSay = wordsTextBox.Text;
            int selectedVolume = volumeTrackBar.Value;
            int selectedVoiceRate = voiceRateTrackBar.Value;
            string selectedGender = genderComboBox.SelectedItem.ToString();
            string selectedAge = ageComboBox.SelectedValue.ToString();

            Type voiceGenderType = typeof(VoiceGender);
            Type voiceAgeType = typeof(VoiceAge);

            //convert the selectedGender value to a VoiceGender
            VoiceGender gender = (VoiceGender)Enum.Parse(voiceGenderType, selectedGender);
            //convert the selectedAge value to a VoiceAge
            VoiceAge age = (VoiceAge)Enum.Parse(voiceAgeType, selectedAge);

            //specify the volume for our SpeechSynthesizer object
            speechSynth.Volume = selectedVolume;
            //specify the rate  for our SpeechSynthesizer object
            speechSynth.Rate = selectedVoiceRate;
            //specify the voice info by using hints regarding the gender and age
            speechSynth.SelectVoiceByHints(gender, age);
            //say the message
            speechSynth.SpeakAsync(messageToSay);
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            speechSynth.Speak("Hello, World!");
        }

        /// <summary>
        /// Bind the enums to our combobox
        /// </summary>
        private void BindData()
        {
            BindAgeToComboBox();
            BindGenderToComboBox();
        }

        /// <summary>
        /// bind the VoiceGender enum to our combobox
        /// </summary>
        private void BindGenderToComboBox()
        {
            //convert the enumeration to a string array
            Array voiceGenderArray = Enum.GetValues(typeof(VoiceGender));
            //bind the array to the datasource of our combobox
            genderComboBox.DataSource = voiceGenderArray;
        }

        /// <summary>
        /// Bind the VoiceAge enum to our combobox
        /// </summary>
        private void BindAgeToComboBox()
        {
            //convert the enumeration to a string array
            Array voiceAgeArray = Enum.GetValues(typeof(VoiceAge));
            //bind the array to the datasource of our combobox
            ageComboBox.DataSource = voiceAgeArray;
        }
    }
};

As always, you can download the source code for this project here: KeithRull.TalkToMeGoose1.zip (27.46 KB)

I hope I was able to show you how simple it is to add text to speech functionality to your .NET application. Next time I'll show you how to use predefined voices. Till next time ;)

Thursday, September 18, 2008 6:35:57 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET | Fun Stuff | Tutorial
# Wednesday, September 17, 2008

Below is a code snippet that allows you to determine what groups a Windows user is part of.

[C#]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Text;

namespace KeithRull.ActiveDirectory.IdentifyingUserGroups
{
    class Program
    {
        static void Main(string[] args)
        {
            //get the WindowsIdentity of the current user
            WindowsIdentity currentWindowsIdentity = WindowsIdentity.GetCurrent();
            //retrieve the groups that the user belongs to
            IdentityReferenceCollection currentWindowsIdentityGroups = currentWindowsIdentity.Groups;
            //iterate thru each group
            foreach (IdentityReference identity in currentWindowsIdentityGroups)
            {
                //translate the identity into an NTAccount identity
                IdentityReference ntAccountIdentityReference = identity.Translate(typeof(NTAccount));
                //get the value
                string groupName = ntAccountIdentityReference.ToString();
                //print to console
                Console.WriteLine(groupName);
            }
            //pause
            Console.ReadLine();
        }
    }
}

[VB.NET]

Imports System 
Imports System.Collections.Generic 
Imports System.Linq 
Imports System.Security.Principal 
Imports System.Text 

Namespace KeithRull.ActiveDirectory.IdentifyingUserGroups 
    Class Program 
        Private Shared Sub Main(ByVal args As String()) 
            'get the WindowsIdentity of the current user 
            Dim currentWindowsIdentity As WindowsIdentity = WindowsIdentity.GetCurrent() 
            'retrieve the groups that the user belongs to 
            Dim currentWindowsIdentityGroups As IdentityReferenceCollection = currentWindowsIdentity.Groups 
            'iterate thru each group 
            For Each identity As IdentityReference In currentWindowsIdentityGroups 
                'translate the identity into an NTAccount identity 
                Dim ntAccountIdentityReference As IdentityReference = identity.Translate(GetType(NTAccount)) 
                'get the value 
                Dim groupName As String = ntAccountIdentityReference.ToString() 
                'print to console 
                Console.WriteLine(groupName) 
            Next 
            'pause 
            Console.ReadLine() 
        End Sub 
    End Class 
End Namespace 

HTH

 

Wednesday, September 17, 2008 9:21:38 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET | ActiveDirectory

Would you agree? ;)

Wednesday, September 17, 2008 7:59:43 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Fun Stuff | Your Career
Archive
<October 2008>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Keith Rull
Sign In
Statistics
Total Posts: 271
This Year: 0
This Month: 0
This Week: 0
Comments: 182
Themes
Pick a theme:
All Content © 2010, Keith Rull
DasBlog theme 'Business' created by Christoph De Baene (delarou)