Mohammed Atef’s Technical blog

Running windows command shell using xp_cmdshell

Introduction

In this post i am going to share with you how to use xp_cmdshell stored procedure for running windows command shell.

xp_cmdshell is system stored procedure that used to run Windows command shell and passes in a string for execution. Any output is returned as rows of text.

Synatx

xp_cmdshell { ‘command_string’ } [ , no_output ]

where command_string Is the string that contains a command to be passed to the operating system. command_string is varchar(8000) or nvarchar(4000) and no_output Is an optional parameter, specifying that no output should be returned to the client.

Enable XP_cmdshell

If you tried to run this stored procedure and you have error says, access denied, you have to enable xp_cmdshell using below SQL script.

   1: EXEC
   2: sp_configure 'show advanced options', 1
   3: GO
   4: RECONFIGURE
   5: GO
   6: EXEC
   7: sp_configure 'xp_cmdshell', 1
   8: GO
   9: RECONFIGURE
  10: GO

Executing vb application without parameter

If you have a .net windows console application named helloworld.exe and it requires to run it from SQL you can use below list of SQL script

   1: declare @cmd varchar(500)
   2: select @param1=rolename,@param2=solutionname from roles where id in
   3: set @cmd='cmd /C "C:\helloworld.exe'
   4: exec xp_cmdshell  @cmd

Executing vb application with two parameters

otherwise, if you have an exe requires two parameters to run it, you can use below SQL Script.

   1: declare @cmd varchar(500)
   2: declare @param1 varchar(50)
   3: declare @param2 varchar(50)
   4: select @param1='param1',@param2='param2'
   5: set @cmd='cmd /C "C:\helloworld.exe '+@param1+' '+@param2+'"'
   6: exec xp_cmdshell  @cmd

Conclusion

above post we saw how to use xp_cmdshell with different modes of needs, hope it is helped.

Advertisements

May 30, 2013 Posted by | .Net 2010, C#,VB.Net, Developement | , , , , | Leave a comment

Link Asp.net Dynamic Data Entity item to customized web pages

Introduction

When we build ASP.NET applications that sit on top of a data store of some kind, there are always a set of common tasks that we need to provide a UI for. Just a few of these patterns are listed here:
Entity Lists — Display a list of rows in a table.
Detail Form — Displays the details of a single entity.
Edit Form — Enables the user to edit the details of a single entity.
Create — Adds a new entity to a list.
Delete — Deletes an entity from a list.
Navigation — Provides Search, Filter, Sort, and Paginate lists of entities.

Problem definition

sometimes we need to link one of entity list to another customized screens we have implemented before, so how we can do this task?

Solution

Here we are going to link one of listed entities in web application entities list to another existing or customized page throw the binding event of Grid View of listed entities.

so if we have assumed that the entity name called Site and the customized page called siteslist.aspx, we can write the following lines of codes to redirect to this customized page when user select Site entity from entities list

 1: protected void Menu1_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
 2:         {
 3:             if(e.Row.RowIndex!=-1)
 4:             {
 5:                if (((System.Web.DynamicData.DynamicHyperLink)e.Row.Cells[0].Controls[1]).Text == "Site")
 6:                 {
 7:                     ((System.Web.DynamicData.DynamicHyperLink)e.Row.Cells[0].Controls[1]).NavigateUrl = Request.Url.ToString().Trim().ToLower().Replace("default.aspx","SitesList.aspx");
 8:                 }
 9:              }
 10:         }

I think these few lines of code is very clear as shown above i have get the grid view row that has Site entity and replaced it’s NavigateUrl with the new siteslist.aspx page.

Note, there is very important note that you should use customized screen like siteslist.aspx which note linked to master page if this page in the same web application else you can use any kind of web pages.

I Hope that helped

May 10, 2011 Posted by | .Net 2010 | , , , | 1 Comment

Workflow Foundation 4.0 Web Service

Introduction

The new Workflow has introduced new project type called WCF Workflow Service Application that can be hosted in a web service, which provides an ideal way to expose workflow solutions to non-workflow clients such as web applications. A web service receives a request, performs some appropriate processing, and returns a response.

Sample senario

The new project we will create is a BookInventory module used for looks up the specified book and returns the status of each copy that the library owns.

Implementation

To start using the new WCF Workflow service open Visual Studio 2010 and select files ->New project and select WCF Workflow service Application from list of project templates available for Workflow as shown in the below picture

clip_image002

You could name enter project name “WCFSampleWF”, once we have created the new project you will find new file added to your project called BookInventory.xamlx this file will contains the following (Sequence, Receive and Send) activities as shown in the below picture

clip_image002[16]

Now we are going to build the service contract Interface and it’s implementation class also we are going to build class that will hold the Book Info, to do that we are going to add new *.cs file named “BookInfo” that will contain the following implementation list of codes.

 1: using System;
 2: using System.Collections.Generic;
 3: using System.Runtime.Serialization;
 4: using System.ServiceModel;
 5:
 6: namespace BookInventory
 7: {
 8:     /*****************************************************/
 9:     // Define the service contract, IBookInventory
 10:     // which consists of a single method, LookupBook() 
 11:     /*****************************************************/
 12:     [ServiceContract]
 13:     public interface IBookInventory
 14:     {
 15:         [OperationContract]
 16:         BookInfoList LookupBook(BookSearch request);
 17:     }
 18:     /*****************************************************/
 19:     // Define the request message, BookSearch
 20:     /*****************************************************/
 21:     [MessageContract(IsWrapped = false)]
 22:     public class BookSearch
 23:     {
 24:         private String _ISBN;
 25:         private String _Title;
 26:         private String _Author;
 27:
 28:         public BookSearch()
 29:         {
 30:         }
 31:         public BookSearch(String title, String author, String isbn)
 32:         {
 33:             _Title = title;
 34:             _Author = author;
 35:             _ISBN = isbn;
 36:         }
 37:         #region Public Properties
 38:         [MessageBodyMember]
 39:         public String Title
 40:         {
 41:             get { return _Title; }
 42:             set { _Title = value; }
 43:         }
 44:         [MessageBodyMember]
 45:         public String Author
 46:         {
 47:             get { return _Author; }
 48:             set { _Author = value; }
 49:         }
 50:         [MessageBodyMember]
 51:         public String ISBN
 52:         {
 53:             get { return _ISBN; }
 54:             set { _ISBN = value; }
 55:         }
 56:         #endregion Public Properties
 57:     }
 58:     /*****************************************************/
 59:     // Define the BookInfo class
 60:     /*****************************************************/
 61:     [MessageContract(IsWrapped = false)]
 62:     public class BookInfo
 63:     {
 64:         private Guid _InventoryID;
 65:         private String _ISBN;
 66:         private String _Title;
 67:         private String _Author;
 68:         private String _Status;
 69:
 70:         public BookInfo()
 71:         {
 72:         }
 73:
 74:         public BookInfo(String title, String author, String isbn,
 75:             String status)
 76:         {
 77:             _Title = title;
 78:             _Author = author;
 79:             _ISBN = isbn;
 80:             _Status = status;
 81:             _InventoryID = Guid.NewGuid();
 82:         }
 83:         #region Public Properties
 84:         [MessageBodyMember]
 85:         public Guid InventoryID
 86:         {
 87:             get { return _InventoryID; }
 88:             set { _InventoryID = value; }
 89:         }
 90:
 91:         [MessageBodyMember]
 92:         public String Title
 93:         {
 94:             get { return _Title; }
 95:             set { _Title = value; }
 96:         }
 97:         [MessageBodyMember]
 98:         public String Author
 99:         {
 100:             get { return _Author; }
 101:             set { _Author = value; }
 102:         }
 103:         [MessageBodyMember]
 104:         public String ISBN
 105:         {
 106:             get { return _ISBN; }
 107:             set { _ISBN = value; }
 108:         }
 109:         [MessageBodyMember]
 110:         public String status
 111:         {
 112:             get { return _Status; }
 113:             set { _Status = value; }
 114:         }
 115:         #endregion Public Properties
 116:     }
 117:     /*****************************************************/
 118:     // Define the response message, BookInfoList, which
 119:     // is a list of BookInfo classes
 120:     /*****************************************************/
 121:     [MessageContract(IsWrapped = false)]
 122:     public class BookInfoList
 123:     {
 124:         private List<BookInfo> _BookList;
 125:
 126:         public BookInfoList()
 127:         {
 128:             _BookList = new List<BookInfo>();
 129:         }
 130:         [MessageBodyMember]
 131:         public List<BookInfo> BookList
 132:         {
 133:             get { return _BookList; }
 134:         }
 135:     }
 136: }

The above code has the following classes and interface

1- IBookInventory is The service contract Interface that contains a single method called LookupBook(). It is has one paramter BookSearch class that has various properties that can be used to find the desired book, such as Author and Title. It returns a BookInfoList class, which contains a collection of BookInfo classes.

2- BookSearch is a class used for building the request that hold the Book Search criteria If you do not have experince about WCF service you should know that The MessageContract attribute is used on a class that defines the data types or contracts that will be added to a message header or body of your WCF service, and the class contains this attribute should have another attribute called MessageBodyMember for properties that will be used in the WCF request or response.

3- BookInfo is a class that hold book info and you can notice that it has MessageContract and MessageBodyMember attributes which means it will be used be service request or response

4- BookInfoList is a class Define the response message, BookInfoList, which is a list of BookInfo classes.

Now we are going to Configure the Send and receive activities, so please follow these steps

a- select the “ReceiveRequest” activity. In the Properties window, Enter the OperationName as LookupBook

b- From the workflow designer, click the Variables control at the bottom left. You’ll notice that the template created a couple of variables for you. The handle variable is used to correlate the response with the same instance that sent the request. The data variable was set up as the data being passed in.

Select the data variable and press the Delete key to remove it, Create two new variables.

For the first one, enter the Name as search; for the Variable type, select Browse for Types, In the dialog that appears, expand the WFFAndWCF->BookInventory assembly and choose the BookSearch class.

For the second variable, enter the Name as result. For the Variable type property, choose Browse for Types and then select the BookInfoList class

c- On the workflow designer, the “ReceiveRequest” activity has a View message link for the Content property. Click it to display the dialog that is used to define the incoming message. The input can be defined in two ways: a message or a collection of parameters. For now, make sure that the Message radio button is selected.For the Message data property, enter search. It specifies that the incoming message should be stored in the search variable. For the Message type, select BookInventory.BookSearch.

d- Select the “SendResponse” activity and click its View message link. Again, make sure that the Message radio button is selected. For the Message data property, enter result; for the Message type property, select the BookInfoList class.

For the Message data property, enter search.

Creating Custom activity for Looks up Book Status

We will create a custom activity to perform the “lookup.” Actually, it will simply return

some hard-coded data and to do that please follow these few steps

a- From the Solution Explorer, right-click the WCFSampleWF project and choose Add -> New Item. In the Add New Item dialog, select the Code Activity template from the Workflow category. Enter the Name as “PerformLookup.cs”

b- Enter the implementation of the PerformLookup activity, as shown in Listing below

 1: using System;
 2: using System.Collections.Generic;
 3: using System.Linq;
 4: using System.Text;
 5: using System.Activities;
 6: namespace BookInventory
 7: {
 8:
 9:     public sealed class PerformLookup : CodeActivity
 10:     {
 11:         public InArgument<BookSearch> Search { get; set; }
 12:         public OutArgument<BookInfoList> BookList { get; set; }
 13:         protected override void Execute(CodeActivityContext context)
 14:         {
 15:             string author = Search.Get(context).Author;
 16:             string title = Search.Get(context).Title;
 17:             string isbn = Search.Get(context).ISBN;
 18:             BookInfoList l = new BookInfoList();
 19:             l.BookList.Add(new BookInfo(title, author, isbn, "Available"));
 20:             l.BookList.Add(new BookInfo(title, author, isbn, "CheckedOut"));
 21:             l.BookList.Add(new BookInfo(title, author, isbn, "Missing"));
 22:             l.BookList.Add(new BookInfo(title, author, isbn, "Available"));
 23:             BookList.Set(context, l);
 24:         }
 25:     }
 26: }

The above list is very clear it is creating two input/ouput arguments called search and booklist for using in send request and receive response from in the Workflow activities, then in the execute it is retrieving search criteria from the search argument and build collection of bookinfo and set booklist argument with the generated list of bookinfo if you did not understand how two build Custom Code activity please visit the following link WFF custom code activity.

c- build the project and opened BookInventory.xamlx file you will notice that the custom PerformLookup activity is added in your Toolbox

d- Drag a PerformLookup activity between the “Receive Request” and “Send Response” activities.

e- Select the PerformLookup activity. In the Properties window, for the BookList property enter result;for the Search property, enter search.

Testing the Service the new Visual Studio automatically starts the WCF Test Client. This is a very handy utility. It loads the web service and discovers the methods that are provided.all you need to press f5 and you find the below figure that shown the test client utility:

clip_image002[18]

As shown in the above figure the left pane contains the methods that are provided by the WCF service once you Double-click the LookupBook() method, the upper portion of the right pane will provide a place for you to enter the contents of the incoming message. Enter an author, ISBN number, and title; then click the Invoke button. You should see results similar to the ones shown bottom grid found in the same figure.

Creating a Client Workflow

Now we are going to build and client Workflow application that will use the created WCF application we have finished before, simply we can do that in few steps as shown below

a- Right click into WCFSampleWF solution name and choose Add -> New Project. Select the Workflow Console Application template from installed templates related to workflow in the left pane of create new project window and for the project name, enter BookLookup

b-From the Solution Explorer, right-click the BookLookup project and choose Add Service Reference and add the following url into address attribute http://localhost:49570/BookInventory.xamlx

, press GO button and finally enter the name of namespace property as “BookEnventoryWCF”.

c- Once you have built the solution you will find new activity added to your toolbar called LookupBook as shown in the below figure

clip_image002[20]

d- Drag that LookupBook activity to you Workflow

e- create arguments that used by the LookupBook activities as show in the below figure

clip_image002[22]

Note that the BookList argument should be of type “BookLookupClientWF.BookEnventoryWCF.BookInfo[]”

f- Set the LookupBook properties to the with the matches argument names

g- Open the Program.cs file in the BookLookupClientWF project. add The implementation for this file as shown in Listing below

 1: using System;
 2: using System.Linq;
 3: using System.Activities;
 4: using System.Activities.Statements;
 5: using System.Collections.Generic;
 6: using BookLookupClientWF.BookEnventoryWCF;
 7:
 8: namespace BookLookupClientWF
 9: {
 10:
 11:     class Program
 12:     {
 13:         static void Main(string[] args)
 14:         {
 15:             // create dictionary with input arguments for the workflow
 16:             IDictionary<string, object> input = new Dictionary<string, object>
 17:             {
 18:             { "Author" , "Margaret Mitchell" },
 19:             { "Title" , "Gone with the Wind" },
 20:             { "ISBN" , "1234567890123" }
 21:             };
 22:             // execute the workflow
 23:             IDictionary<string, object> output =
 24:             WorkflowInvoker.Invoke(new Workflow1(), input);
 25:             BookInfo[] l = output["BookList"] as BookInfo[];
 26:             if (l != null)
 27:             {
 28:                 foreach (BookInfo i in l)
 29:                 {
 30:                     Console.WriteLine("{0}: {1}, {2}",
 31:                     i.Title, i.status, i.InventoryID);
 32:                 }
 33:             }
 34:             else
 35:                 Console.WriteLine("No items were found");
 36:             Console.WriteLine("Press ENTER to exit");
 37:             Console.ReadLine();
 38:         }
 39:     }
 40: }

i-  run the application you will find the following message printed in the console screen

Gone with the Wind: Available, 58ab51cd-2796-4b32-a7be-21170f1e922b

Gone with the Wind: CheckedOut, 64406a94-a6ef-45a7-8373-066f5f991134

Gone with the Wind: Missing, a37186ec-faa7-4e6b-8226-484f17075998

Gone with the Wind: Available, e34d39e5-aafa-4fd3-8000-664809b7e98d

Press ENTER to exit

You can download the complete source code from here

Back to other Workflow Foundation 4.0  posts

I hope that helped

May 10, 2011 Posted by | .Net 2010 | , , , | 2 Comments

Workflow Foundation 4.0 Collections

Introduction

In this post we will see an important built in activities comes with Workflow foundation 4.0., these built-in activities enable you to manipulate a collection in your workflow. this post guide you to do the most required actions for manipulating collections like add,remove and delete items from collection and sorting, searching and clearing the collection.

We will build a console application that demonstrates these activities using a Book Store application.

Building Book Store application
To build the Book Store application you should follow the below steps

1- Create new console application and add System.Activities reference to the new project

2- Open the program.cs file and add the following list of code for declaring BookStoreListItem this class contains a few public properties that store information about an item to be stored.

   1: public class BookStoreListItem
   2:     {
   3:         public string Description { get; set; }
   4:         public int Quantity { get; set; }
   5:         public decimal UnitPrice { get; set; }
   6:         public string Author { get; set; }
   7:         public string BookName { get; set; }
   8:         public BookStoreListItem(string description, int quantity, decimal unitPrice,string author, string bookName)
   9:         {
  10:             Description = description;
  11:             Quantity = quantity;
  12:             UnitPrice = unitPrice;
  13:             BookName = bookName;
  14:             Author = author;
  15:         }
  16:         public BookStoreListItem(string bookName)
  17:         {
  18:             BookName= bookName;
  19:         }
  20:     }

3- Initiate the Workflow by adding the following namespace to the top of program.cs class

using System.Activities.Expressions; now add the following list of code after the closed practices for the main method in the program.cs class

   1: private static Activity CollectionWF()
   2:         {
   3:             // myList is a collection of ListItem objects
   4:             Variable<ICollection<BookStoreListItem>> myList = new Variable<ICollection<BookStoreListItem>>()
   5:             {
   6:                 Name = "MyList",
   7:                 Default = new LambdaValue<ICollection<BookStoreListItem>>
   8:                     (env => new List<BookStoreListItem>())
   9:             };
  10:             return new Sequence
  11:             {
  12:                 Variables = { myList },
  13:                 Activities =
  14:                 {
  15:                     new WriteLine
  16:                     {
  17:                         Text = "Workflow starting..."
  18:                     },
  19:                     new AddToCollection<BookStoreListItem>
  20:                     {
  21:                         Collection = myList,
  22:                         Item = new LambdaValue<BookStoreListItem>
  23:                         (env => new BookStoreListItem("New WorkFlow 4.0 book", 5, 50,"Mohammed", "WorkFlow 4.0"))
  24:                     },
  25:                     new AddToCollection<BookStoreListItem>
  26:                     {
  27:                         Collection = myList,
  28:                         Item = new LambdaValue<BookStoreListItem>
  29:                         (env => new BookStoreListItem("New Linq 4.0 book", 3, 30,"Sherif", "LINQ 4.0"))
  30:                     },
  31:                     new AddToCollection<BookStoreListItem>
  32:                     {
  33:                         Collection = myList,
  34:                         Item = new LambdaValue<BookStoreListItem>
  35:                         (env => new BookStoreListItem("New Windows Communication Foundation 4.0 book", 8, 80,"Atef", "WCF 4.0"))
  36:                     },
  37:                     new AddToCollection<BookStoreListItem>
  38:                     {
  39:                         Collection = myList,
  40:                         Item = new LambdaValue<BookStoreListItem>
  41:                         (env => new BookStoreListItem("Visual studio 2010 book", 15, 40,"Khalid", "VS 2010"))
  42:                     },
  43:                     new WriteLine
  44:                     {
  45:                         Text = "Workflow ended"
  46:                     }
  47:                 }
  48:             };
  49:         }

This workflow defines a variable that is a collection of BookStoreListItem classes named myList. The variable can be any typeof collection that supports the ICollection interface.the LambdaValue Represents a lambda expression used as an r-value, which supports binding of In arguments so it is bind the default value of myList with the returned new instance of BookStoreListItem class .

After that we are going to build the sequence activity for our workflow and the sequence activity will have the following activities

a- writeline activity that printing “Workflow starting…”

b- four AddToCollection activity that used for adding new item of BookStoreListItem to myList

c- another writeline activity to print “Workflow ended…”

4- Now we need to invoke the workflow, so please add the following lines of code in the main method at program.cs class

   1: WorkflowInvoker.Invoke(CollectionWF());
   2: Console.WriteLine("Press ENTER to exit");
   3: Console.ReadLine();

These few line of code used to invoke the workflow by calling collectionWF into the Invoke method.

If you have run the application now you will find the following lines printed

Workflow starting…

Workflow ended…

Press ENTER to exit

5- Printing Collection , we will provide a way to display the contents of the books list, to do that right-click the project and choose Add new Item and select Class, For the class name, enter PrintBooksList.cs. The implementation of this class is shown in Listing below

   1: using System;
   2: using System.Activities;
   3: using System.Collections.Generic;
   4: namespace WFFBookStoreApp
   5: {
   6:     public sealed class PrintBooksList: CodeActivity
   7:     {
   8:         public InArgument<ICollection<BookStoreListItem>> Collection { get; set; }
   9:
  10:         protected override void Execute(CodeActivityContext context)
  11:         {
  12:             ICollection<BookStoreListItem> list =
  13:             this.Collection.Get<ICollection<BookStoreListItem>>(context);
  14:             if (list.Count == 0)
  15:             {
  16:                 Console.WriteLine("The Book list is empty");
  17:             }
  18:             else
  19:             {
  20:                 foreach (BookStoreListItem l in list)
  21:                 {
  22:                     Console.WriteLine("Book Named {0} has the following information :", l.BookName);
  23:                     Console.WriteLine("(Description:{0} ,Quantity: {1},Price: {2} ,Author {3})",
  24:                     l.Description,l.Quantity.ToString(), l.UnitPrice, l.Author);
  25:                 }
  26:                 Console.WriteLine();
  27:             }
  28:         }
  29:     }
  30: }

This custom activity receives the collection as an input argument. It expects a collection of BookStoreListItem classes. the overridden execute method first check if the list empty or not, if yes it is printing the book list is empty message, else it is loop throw the list and print each book item information, this code is very simple you can understand but if you do not know how to create custom activity please visit the following link WFF 4.0 custom activity.

6- To use this custom activity, Open the program.cs file and add the following activity definition to the collectionWF () method before the final writeline activity

   1: new PrintBooksList
   2:                     {
   3:                         Collection=myList
   4:                     },

If you run the application now you will find the following message printed

clip_image002

7- Sorting the collection, we will provide a way to sort the books list by book price, to do that right-click the project and choose Add new Item and select Class, For the class name, enter SortBooksList.cs. The implementation of this class is shown in Listing below

   1: using System;
   2: using System.Activities;
   3: using System.Collections.Generic;
   4: namespace WFFBookStoreApp
   5: {
   6:     public sealed class SortBooksList : CodeActivity
   7:     {
   8:         public InOutArgument<ICollection<BookStoreListItem>> Collection { get; set; }
   9:         protected override void Execute(CodeActivityContext context)
  10:         {
  11:             ICollection<BookStoreListItem> tempList = this.Collection.Get<ICollection<BookStoreListItem>>(context);
  12:             if (tempList.Count > 0)
  13:             {
  14:                 List<BookStoreListItem> sortedList = new List<BookStoreListItem>(tempList);
  15:                 ItemComparer c = new ItemComparer();
  16:                 sortedList.Sort(c as IComparer<BookStoreListItem>);
  17:                 Collection.Set(context, sortedList as ICollection<BookStoreListItem>);
  18:             }
  19:         }
  20:     }
  21:     public class ItemComparer : IComparer<BookStoreListItem>
  22:     {
  23:         public int Compare(BookStoreListItem x, BookStoreListItem y)
  24:         {
  25:             // Handle null arguments
  26:             if (x == null && y == null)
  27:                 return 0;
  28:             if (x == null)
  29:                 return -1;
  30:             if (y == null)
  31:                 return 1;
  32:             // Perform comparison based on the priority
  33:             if (x.UnitPrice == y.UnitPrice)
  34:                 return 0;
  35:             if (x.UnitPrice > y.UnitPrice)
  36:                 return 1;
  37:             else
  38:                 return -1;
  39:         }
  40:     }
  41: }

This custom activity receives the collection as an input argument and return the same argument after sorting it. It expects a collection of BookStoreListItem classes .the overridden Execute() method of this activity takes a collection as both an input and output argument.The Sort() method of the List class is used to perform the sort, but you must supply a class that implements the IComparer interface because the standard implementation will not know how to sort BookStoreListItem objects. The IComparer interface provides a single method called Comparer (), which receives two objects (x and y) as input parameters. It returns 0 if the two objects are equal, 1 if x is greater than y, and -1 if x is less than y.

8- To use this custom activity, Open the Program.cs file and add the following activity definition to the collectionWF () method before the final writeline activity

   1: new SortBooksList
   2: {
   3:     Collection=myList
   4: },
   5: new WriteLine
   6: {
   7:     Text = "Books List sorted by Price"
   8: },
   9: new PrintBooksList
  10: {
  11:     Collection=myList
  12: },

If you run the application now you will find the following message printed

clip_image002[7]

if you have reviewed the printed lines in console, you will find the new books listed after line “books list sorted by price are order desc by price.

9- Searching in the collection, now we are going to use built in activity in Workflow Foundation 4.0 like ExistsInCollection, so we will check if the item found in the book list or not.

As the ExistsInCollection should iterate between books list items so it is require to use Equals() methods which mean we need to implement this method to our BookStoreListItem class, For our purposes, you should consider two items equal if they have the same name,To do that add the following list of code to BookStoreListItem class in program.cs file

   1: public override bool Equals(object obj)
   2: {
   3:     BookStoreListItem i = obj as BookStoreListItem;
   4:     if (i == null)
   5:         return false;
   6:     else
   7:     {
   8:         if (i.BookName == this.BookName)
   9:             return true;
  10:         else
  11:             return false;
  12:     }
  13: }
  14: public override int GetHashCode()
  15: {
  16:     return base.GetHashCode();
  17: }

The Equals() method cast the input object to a BookStoreListItem and returns True if the BookName property matches. When overriding the Equals() method, the compiler expects you to also override the GetHashCode() method. This implementation simply calls the base method

10- Now , we can use ExistsInCollection to do that add the following lines of code before the final writeline activity

   1: public override bool Equals(object obj)
   2:        {
   3:            BookStoreListItem i = obj as BookStoreListItem;
   4:            if (i == null)
   5:                return false;
   6:            else
   7:            {
   8:                if (i.BookName == this.BookName)
   9:                    return true;
  10:                else
  11:                    return false;
  12:            }
  13:        }
  14:        public override int GetHashCode()
  15:        {
  16:            return base.GetHashCode();
  17:        }
  18:

If you have run the application now you will see this line printed before workflow ended

“LINQ 4.0 Book has been added before”

11- Remove item from Collection, Workflow Foundation 4.0 has activity named RemoveFromCollection that is responsible for removing item from collection it very easy in implementation, we will use it to remove book named “LINQ 4.0“,to do that add the following line of code before the final writeline activity

   1: new WriteLine
   2: {
   3:     Text = "Removing LINQ 4.0 book from Books Store..."
   4: },
   5: new RemoveFromCollection<BookStoreListItem>()
   6: {
   7:     Collection = myList,
   8:     Item = new LambdaValue<BookStoreListItem>
   9:         (env => new BookStoreListItem("LINQ 4.0"))
  10: },
  11: new PrintBooksList()
  12: {
  13:     Collection = myList
  14: },

if you have run the application now you will see the following lines printed before workflow ended line

clip_image002[9]

12- Clearing the collection, Workflow Foundation 4.0 has built in activity to clear collection named ClearCollection to use this activity add the following lines of code before the final writeline activity

   1: new ClearCollection<BookStoreListItem>()
   2: {
   3:     Collection = myList
   4: },
   5: new PrintBooksList()
   6: {
   7:     Collection = myList
   8: },

If you have run the application now you will find line printed before workflow ended that says

“The book list is Empty”

Conclusion:

I was trying to learn you how WFF 4.0 are manipulation with collection,you can download The complete implementation of that post from here and you can return back to workflow posts list here

Back to other Workflow Foundation 4.0  posts

I Hope that helped

September 26, 2010 Posted by | .Net 2010 | , , , , , , | 1 Comment

Workflow Foundation 4.0 Custom activities

WFF 4.0 helps you to implement you own custom activity. sure creating custom activity is very important part that all Workflow developers are interested in.the new Workflow Foundation 4.0 give you two ways of generating custom activities.
As we need to prove concept only, my custom activity will be simple, just I am going to build custom activity that print the message “Hello FirstName Last Name” this custom activity taking two input parameters First Name and Last Name and return the full message,let’s see how to implement this simple example by Workflow Foundation 4.0.

Using Code Activity template

Code activity template give you advantage to inherit the codeactivity class and build your custom activity from scratch but the new Workflow Foundation helps you to do that in easy way, so to implement the new custom activity follow the following steps

1- Open Visual Studio 2010 and select file->new project->workflow->workflow consol application

2- In the name textbox write CustomactivitySample as the project name

3- After the solution has opened right click in the project name and select add new item that will open the list of items as shown in the below picture

clip_image002

select code activity and enter code activity name such as “HelloMsg
4- By default you with find the below list of code has been generated in your new file that named HelloMsg.cs

   1: public sealed class HelloMsg : CodeActivity
   2:     {
   3:         // Define an activity input argument of type string
   4:         public InArgument<string> Text { get; set; }
   5:         // If your activity returns a value, derive from CodeActivity<TResult>
   6:         // and return the value from the Execute method.
   7:         protected override void Execute(CodeActivityContext context)
   8:         {
   9:             // Obtain the runtime value of the Text input argument
  10:             string text = context.GetValue(this.Text);
  11:         }
  12:     }

5- Now we are going to add our code for printing hello message

– First we will prepare the activity parameters, so replace line no 4 in the above codes list with the following list of codes

   1: public InArgument<string> FirstName { get; set; }
   2: public InArgument<string> LastName { get; set; }
   3: public OutArgument<string> HelloMessgae { get; set; }

As shown in the above codes list we have declared two input parameters first name and last name and one output parameter for returning the complete hello message.

– The last step for implementing this custom activity is to add code for using input parameters and concatenating it to return the complete hello message, so please replace line 10 at the codes list in step 4 with the following list of codes

   1: string fname = context.GetValue(this.FirstName);
   2: string lname = context.GetValue(this.LastName);
   3: string completeMsg = " Hello " + fname +" "+ lname;
   4: context.SetValue(this.HelloMessgae, completeMsg);

6- Build the project to refresh the toolbar, and you will notice new activity hellomsg activity has been added to the toolbar.

7- Open Workflow1.xaml in designer view and drag sequence activity then drag hellomsg and writeline activity by ordered in the new added sequence activity

8- Create variable named fullname and has data type string from the variables window at bottom of the workflow1 designer

9-Open the writeline property windows and set the text property to the new created variable name in the previous step

10- Open the hellomsg property window and set it is properties as follow:

a- FirstName: “Mohammed”

b- Last Name: “Atef”

c- HelloMessage: fullname which added in step no 8

Finally run the application you will see this message in the console window

“Hello Mohammed Atef”

Using Activity

Using the activity you can create your own activity and use it in another work flow as independent activity and you can pass parameters between your activity and the main workflow designer

This kind of activities is very simple as you are using the workflow designer with all toolbar activities available to implement you custom activity.

We are going to do the same business scenario in the previous example but we will add the following message before the hello message “Custom Activity using Designer.” this only to determine the message printed for each custom activity.

Now , to implement the new custom activity follow the following steps

1- Write click into the project name and select add new item then select activity icon from the windows as shown in picture below

clip_image002[4]

name that activity hellomsgActivity.xaml

2- Drag sequence activity to the new created activity named hellomsgActivity.xaml and then drag writeline activity into the sequence activity

3- Add two arguments from arguments window below the designer of that activity named hellomsgActivity.xaml

4- Write the following line into the text property of the writeline activity

“Custom Activity using Designer: Hello Mr. ” + FName + LName

5- Build the application

6- Open the main workflow1.xaml in design mode and drag hellomsgActivity activity from the toolbar

7- Open the hellomsgActivity property window and set it is properties as follows

a- FName:”Mohammed”

b-LName:”Atef”

Now Run the application you will find the following messages are printed

Hello Mohammed Atef”

Custom Activity using Designer: Hello Mr. Mohammed Atef”

Now we have finished this example and the main workflow1.xaml should be like the following picture below

clip_image002[6]

You can also download the complete example by source code from here.
Back to other Workflow Foundation 4.0  posts

I hope that helped.

September 26, 2010 Posted by | .Net 2010 | , , , , , | 3 Comments

Workflow Foundation 4.0 Tracking

Introduction

This post will guide you to use extensions for tracking Workflow events while it is executing the defined activities.This is useful for monitoring a workflow’s execution and for triggering external processing.

Tracking
In WF 4.0, tracking is accomplished through tracking participants, which are extensions that are derived
from the TrackingParticipant abstract class.
First of all to implement tracking extensions you need to inherit TrackingParticipant class and overrides the Track() method, which is where most of the work is done. When a trackable event occurs, the workflow instance will enumerate all the extensions and will call the Track() method in any that are derived from the TrackingParticipant base class.
A TrackingRecord is passed into the Track() method. This is an abstract class; the actual instance passed
in will be one of the following classes, which are derived from the TrackingRecord class:
WorkflowInstanceRecord contains data about the workflow instance.
You can use this class to print the Workflow instance ID and Workflow instance state as shown in the below list of codes:

   1: WorkflowInstanceRecord instance = record as WorkflowInstanceRecord;
   2: if (instance != null)
   3: {
   4: Console.WriteLine(String.Format(" InstanceID: {0} State: {1}",instance.InstanceId, instance.State));
   5: }

BookmarkResumptionRecord contains data about the bookmark being resumed.

You can use this class to print the book mark name as shown in the below list of codes:

   1: BookmarkResumptionRecord bookmark = record as BookmarkResumptionRecord;
   2: if (bookmark != null)
   3: {
   4: Console.WriteLine(String.Format(" Bookmark {0} resumed",bookmark.BookmarkName));
   5: }

ActivityStateRecord contains data about a specific activity.

You can use this class to print information about activities hosted in the Workflow instance as shown in the below list of codes:

   1: ActivityStateRecord activity = record as ActivityStateRecord;
   2: if (activity != null)
   3: {
   4: IDictionary<String, object> variables = activity.Variables;
   5: StringBuilder s = new StringBuilder();
   6: if (variables.Count > 0)
   7: {
   8: s.AppendLine(" Variables:");
   9: foreach (KeyValuePair<string, object> v in variables)
  10: {
  11: s.AppendLine(String.Format(" {0} Value: [{1}]",
  12: v.Key, v.Value));
  13: }
  14: }
  15: Console.WriteLine(String.Format(" Activity: {0} State: {1} {2}",
  16: activity.Activity.Name, activity.State, s.ToString()));
  17: }

CustomTrackingRecord contains user-defined data.

You can use this class to print about user-defined data as shown in the below list of codes

   1: CustomTrackingRecord user = record as CustomTrackingRecord;
   2: if ((user != null) && (user.Data.Count > 0))
   3: {
   4: Console.WriteLine(String.Format(" User Data: {0}", user.Name));
   5: foreach (string data in user.Data.Keys)
   6: {
   7: Console.WriteLine(String.Format(" {0} : {1}", data, user.Data[data]));
   8: }
   9: }

To use the tracking extension you should add the tracking extension to the Workflow instance as shown in the below list of codes

   1: i.Extensions.Add(_tracking);
   2: //where i is an instance of WorkflowApplication  
   3: //and _tracking is an instance of class that inherits TrackingParticipant class

Then you should set up the tracking extensions participants by using TrackingProfile collections, A TrackingProfile defines a collection of queries that specify which events are to be tracked by the associated tracking participant. These queries are used to determine if an event is trackable. The queries are stored in the Queries property, which is a collection of classes derived from the abstract TrackingQuery class. There are four derived classes that correspond to the four types of tracking records:

WorkflowInstanceQuery

A WorkflowInstanceQuery is used to define the workflow instance events that should be tracked. These

are the process states that occur at the instance level such as Started, Completed, Unloaded, and so on, To do that you can write the below list of codes:

   1: TrackingProfile = new TrackingProfile()
   2: {
   3:     Name = "TrackingProfileName",
   4:     Queries =
   5:     {
   6:         // For instance data, only track the started and completed events
   7:         new WorkflowInstanceQuery()
   8:         {
   9:             States = { WorkflowInstanceStates.Started,WorkflowInstanceStates.Completed },
  10:         }
  11: }

BookmarkResumptionQuery

In a BookmarkResumptionQuery, you specify the name of the bookmark that you want to track whenever it is resumed. You can specify only a single bookmark in a query. If you want to track multiple bookmarks,

you should create multiple queries—one for each bookmark, To do that you can write the below list of codes:

   1: TrackingProfile = new TrackingProfile()
   2: {
   3:     Name = "TrackingProfileName",
   4:     Queries =
   5:     {
   6:         new BookmarkResumptionQuery()
   7:                       {
   8:                           Name = "GetAssignment"
   9:                       }
  10: }

ActivityStateQuery

An ActivityStateQuery class specifies both the Name of the activity and the State collection (events) that

should be tracked. You can specify an asterisk (*) for either, which indicates that all activities and/or

states should be tracked, To do that you can write the below list of codes:

   1: TrackingProfile = new TrackingProfile()
   2:                 {
   3:                     Name = "ListBoxTrackingProfile",
   4:                     Queries =
   5:                     {
   6:                         // For activity data, track all states of the InvokeMethod
   7:                        new ActivityStateQuery()
   8:                        {
   9:                            ActivityName = "InvokeMethod",
  10:                            States = { "*" },
  11:                        }
  12:                     }
  13: }

CustomTrackingQuery

The CustomTrackingQuery specifies the ActivityName, which indicates the activity that generated the

CustomTrackingRecord and the Name property, which indicates the name given to the CustomTrackingRecord,You can specify an asterisk for either (or both) as the example, above does. When

both are set to *, it indicates that all user events should be tracked, you can do that by typing the below of codes:

   1: TrackingProfile = new TrackingProfile()
   2:                 {
   3:                     Name = "ListBoxTrackingProfile",
   4:                     Queries =
   5:                     {
   6:                         new CustomTrackingQuery()
   7:                         {
   8:                             Name = "*",
   9:                             ActivityName = "*"
  10:                         }
  11:                     }
  12: }

In this post we have understood the Tracking extension and we have learned how to use it also.now you can visit the orher posts about Workflow Foundation for here

I hope that helped.

September 26, 2010 Posted by | .Net 2010 | , , , , , , | 2 Comments

Workflow Foundation 4.0 Extensions

Introduction

Workflow foundation Extensions allow you to add configurable behavior to a workflow solution. The activities that you include in your workflow define the steps that are performed, while the extensions provide the operating environment that these activities are executed in, the persistence extension is not aware of what activities are executed; the extension however, provides the ability to persist those activities (whatever they might be) to a durable store.

SQL Persistence Extension

There are two key aspects of extensions that make then extremely useful. First, as was inferred
earlier, they are configurable. For example, the persistence provider that was used SqlWorkflowInstanceStore was designed to use a SQL Server database. Without changing the
application or the workflow definition.
The second aspect of extensions is that they can be accessed both from the application as well as the
workflow activities. This provides a convenient tool for sharing information between the application and
the workflow.

To use SQL Persistence you need to declare a reference to the InstanceStore class that will be used to persist and load the workflow instances :

   1: private InstanceStore _instanceStore;

Then add you need to Loaded event handler and configures the store to do that you need to write the following code

   1: _instanceStore = new SqlWorkflowInstanceStore(_connectionString);
   2: InstanceView view = _instanceStore.Execute(_instanceStore.CreateInstanceHandle(),
   3: new CreateWorkflowOwnerCommand(),TimeSpan.FromSeconds(30));
   4: _instanceStore.DefaultInstanceOwner = view.InstanceOwner;

where the _connectionstring is the DB sql connection string used for your SQL Persistence.above code has an InstanceStore that is an abstract class from which all persistence providers are derived. An instance of the concrete class SqlWorkflowInstanceStore is created, passing the connection string in the constructor.

The parameters to the Execute() method are a handle (provided by InstanceStore ), a command, and a

timeout value. It returns an InstanceView class, which is roughly analogous to a connection handle.

Now you need to setup The Workflow persistence, to do that add the following codes listed below

   1: i.InstanceStore = _instanceStore;//where i is and instance of WorkflowApplication
   2: i.PersistableIdle = (waiea) => PersistableIdleAction.Unload;
   3: i.Run();

The above code configures the workflow instance to be persisted. First, it sets the InstanceStore

property using the reference created as described early. It then provides an event handler for

the PersistableIdle event, which tells the instance to unload itself from memory. It is persisted to the

database prior to being unloaded.

Custom Extensions

here we will learn how to build a custom extension and how to use it in you Workflow. we are going to build simple custom extension that used to store the connection string, Instead of passing the connection string as an input argument, any activity that needs the connection string can access it from this extension.

Assume that we will create class called  that hold the custom extension and implemented as shown in list below

   1: using System;
   2: public class ConStringExtension
   3:     {
   4:         private string _connectionString = "";
   5:
   6:         public DBExtension(string connectionString)
   7:         {
   8:             _connectionString = connectionString;
   9:         }
  10:
  11:         public string ConnectionString { get { return _connectionString; } }
  12:     }

The above code simply defines a private member that holds the connection string. The value of this string

is passed in the class constructor. A public property is provided for accessing this string.To add the new Custom extension to you Workflow instance add the following code

   1: ConStringExtension _dbExtension = new ConStringExtension(_connectionString);
   2: i.Extensions.Add(_dbExtension);

Finally to use this custom extension into code activity add the following line

   1: ConStringExtension ext = context.GetExtension<ConStringExtension>();

I hope you have understand Workflow extensions well ,now you can check other posts about work flow here

I hope that helped.

September 26, 2010 Posted by | .Net 2010 | , , , , , | 1 Comment

Workflow Foundation 4.0

The new Workflow foundation comes with .Net Framework 4.0 that supports building and running the next generation of applications and services. The key components of the .NET Framework are the common language runtime (CLR) and the .NET Framework class library, which includes ADO.NET, ASP.NET, Windows Forms, and Windows Presentation Foundation (WPF), by the way all Visual Studio 2010 IDE are build in XAML language that provides a managed execution environment, simplified development and deployment, and integration with a wide variety of programming languages.

In version 4 of the Microsoft® .NET Framework, Windows Workflow Foundation introduces a significant amount of change from the previous versions of the technology that shipped as part of .NET 3.0 and 3.5.

The significant changes made were necessary to provide the best experience for developers adopting WF and to enable WF to continue to be a strong foundational component that you can build on in your applications.

I have wrote this article to give you a start point to understand and study Workflow Foundation 4.0, so I am going to write series of posts about WFF 4.0 as found in the below below List

I hope that helped

September 20, 2010 Posted by | .Net 2010 | , , , , , | 6 Comments

What’s new in Workflow Foundation 4.0

The New Workflow Foundation 4.0 introduces a significant amount of change from the previous versions of the technology that shipped as part of .NET 3.0 and 3.5. so let’s go quickly to see these new features

  • Designers are built in XAML The designer is based on Windows Presentation Foundation (WPF),so it is taking full advantage of the rich user experience one can build with the declarative UI framework.  Activity developers will use XAML to define the way their activities look and interact with users in a visual design environment.  In addition, it enables non-developers to view and interact with your workflows is now much easier as XAML language is written in XML language that give any non-developers ability to read and understand it.

    For example if you have created new project of Console Workflow and dragged a WriteLine activity in the designer and select the code view you will find the following list of XAML codes

       1: <Activity mc:Ignorable="sap" x:Class="WorkflowConsoleApplication1.Workflow1" sap:VirtualizedContainerService.HintSize="251,240" mva:VisualBasic.Settings="Assembly references and imported namespaces for internal implementation" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
       2: <WriteLine
       3: sad:XamlDebuggerXmlReader.FileName="C:\Temp\DotNet4\WorkflowConsoleApplication1\Workflow1.xaml"
       4: sap:VirtualizedContainerService.HintSize="211,200" />
       5: </Activity>

    I think any non-developer can understand the above list of XAML code

  • Different project templates The new Workflow Foundation 4.0 comes with new project templates as shown in below pictureclip_image002

    The above picture shows only four project templates of Workflow Foundation 4.0 that leads you to simplify project templates for developer. The first project template Activity Designer Library let you create you custom Workflow Foundation Activity with designer, while the second project template leads you to create your custom activity by inheriting the CodeActivity class and the third project template leads you to build new WCF Workflow Service and we are going to explain this project template deeply in another post later finally the last project type help you for creating Console application that contain Workflow Activities.

    If you reviews the below pictures that has list of project template found for Workflow Foundation 3.5 you will understand that new Workflow Foundation 4.0 has summarized and compressed the project templates in better way.

    clip_image002[7]

  • Variable and parameters new windows in the WFF IDE Workflow Foundation 4.0 introduces a helpful window for creating variables and parameters to your Workflow in easy way, the below two pictures show you the new windows generated for defining variables and parameters

    clip_image002[9]

    clip_image002[11]

    First Picture show you how to declare variable to you workflow, as shown there you can define the DataType of you variable, default value and the scope of a variable either the entire workflow or just a specific activity or its children.

    Second picture show you how to define arguments by specifying its name, direction(In,Out,In/Out), argument type and default value.

    If you have used Workflow Foundation 3.5 before you should understand what Workflow Foundation 4.0 has introduced to you for declaring variables and arguments as in WFF 3.5 you should write the following list of codes to define variable

   1: public static DependencyProperty MessageProperty =
   2:     DependencyProperty.Register("Message", typeof(string), typeof(CustomActivity));
   3:
   4:         [DescriptionAttribute("Message")]
   5:         [BrowsableAttribute(true)]
   6:         [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
   7:         public string Message
   8:         {
   9:             get
  10:             {
  11:                 return ((string)(base.GetValue(MessageProperty)));
  12:             }
  13:             set
  14:             {
  15:                 base.SetValue(MessageProperty, value);
  16:             }
  17:         }
  18:

The above bulk of code writes only for defining variable Named message of type string

  • Windows Communication Foundation (WCF) Integration

    Workflow Foundation 4.0 introduce creating services and consuming or coordinating service interactions.  A great deal of effort went into enhancing the integration between WCF and WF.  New messaging activities, message correlation, and improved hosting support, along with fully declarative service definition are the major areas of improvement, We will go deeply throw WCF integration with the new WF in another post later.

  • New built in Activity The new Workflow Foundation 4.0 has a lot of built in activities as follows- New activities for manipulating data such as Assign and collection activities such as AddToCollection.

    – New flow control activities, such as DoWhile, TryCatch, ForEach, Switch, and ParallelForEach.

    – Activities for controlling transactions, such as TransactionScope and Compensate.

    – New messaging activities such as SendContent and ReceiveReply.

    Most of these Activities will be explained in the next post for WFF 4.0 toolbar.

    Back to other Workflow Foundation 4.0  posts

I Hope that Helped

September 20, 2010 Posted by | .Net 2010 | , , , , , | 1 Comment

Master Details GridView with Details inside same GridView

Introduction

I have been worked for implementing Gridview which contain linkbutton in each row that link must be show user details in same row using Detail View Control.

Solution

I have developer normal Gridview and did the following steps

1-drag GridView and Detail view control into my page

2- bind Gridview in page load event

3- add 3 template fields and one command select field

4-add labels with unique names in each template field

5-add the following code in GridView RowCommand Event
 

   1: If e.CommandName = "Select" Then
   2:             Dim userid As String = CType(GridView1.Rows(Integer.Parse(e.CommandArgument)).Cells(0).FindControl("lbluserid"), Label).Text
   3:             DetailsView1.DataSource = GenerateUserDetTable(GenerateUserDetTable(Nothing).Select("userID=" + userid)(0))
   4:             DetailsView1.DataBind()
   5:             GridView1.Rows(Integer.Parse(e.CommandArgument)).Cells.RemoveAt(0)
   6:             GridView1.Rows(Integer.Parse(e.CommandArgument)).Cells.RemoveAt(1)
   7:             GridView1.Rows(Integer.Parse(e.CommandArgument)).Cells(0).Text = ""
   8:             GridView1.Rows(Integer.Parse(e.CommandArgument)).Cells(0).ColumnSpan = 2
   9:             GridView1.Rows(Integer.Parse(e.CommandArgument)).Cells(0).HorizontalAlign = HorizontalAlign.Center
  10:             GridView1.Rows(Integer.Parse(e.CommandArgument)).Cells(0).Controls.Add(DetailsView1)
  11:             Dim lnk As LinkButton
  12:             lnk = New LinkButton
  13:             lnk.CommandName = "Hide"
  14:             lnk.Text = "Hide"
  15:             GridView1.Rows(Integer.Parse(e.CommandArgument)).Cells(1).Text = ""
  16:             GridView1.Rows(Integer.Parse(e.CommandArgument)).Cells(1).Controls.Add(lnk)
  17:         End If

Understanding Code

the whole idea is to remove not needed cells and reset the Column span for the remaining cell and adding detailView into this cell lets see how you can do this

at line 1 i get user is from row that user click show linkbutton there

at lines 5,6 i have removed not needed cells

at lines 8,9,10 i have update remaining cell properties and add Detailview to it

at lines 11 to 16 i have create new linkbutton and replace it with the Show link button

note that GenerateUserDetTable is a method that generating UserDetails Table

you can download the whole project from here


Hope that helped.

September 30, 2009 Posted by | .Net 2010, C#,VB.Net | , , , , , | Leave a comment