Click here to Skip to main content
15,892,674 members
Articles / Desktop Programming / XAML

Hello, WF!

Rate me:
Please Sign up or sign in to vote.
4.52/5 (44 votes)
12 Nov 200611 min read 173.6K   741   101  
Explains the very basics of Windows Workflow Foundation, using The World's Stupidest WF Application.
using System;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;

namespace FirstWFLibrary
{
	#region PromptForUserName

	/// <summary>
	/// Asks the user for their name.
	/// </summary>
	public class PromptForUserName : Activity
	{
		protected override ActivityExecutionStatus Execute( ActivityExecutionContext executionContext )
		{
			Console.Write( "Please enter your name and press Enter: " );
			return ActivityExecutionStatus.Closed;
		}
	}

	#endregion // PromptForUserName

	#region ReadConsoleLine

	/// <summary>
	/// An activity which represents reading a line of text from the console.
	/// </summary>
	public class ReadConsoleLine : Activity
	{
		#region InputText Property

		private string inputText;
		public string InputText
		{
			get { return this.inputText; }
		}

		#endregion // InputText Property

		#region Execute [override]

		protected override ActivityExecutionStatus Execute( ActivityExecutionContext executionContext )
		{
			// Create a WorkflowQueue, which allows this activity to "bookmark" where it should
			// continue executing once the external input arrives (in this case, a string is read
			// from the console).
			WorkflowQueue workflowQueue = this.GetWorkflowQueue( executionContext );

			// Attach a handler which processes the external input.
			workflowQueue.QueueItemAvailable += ProcessQueueItemAvailable;

			// Attach a handler which cleans up after the input has been processed.
			workflowQueue.QueueItemAvailable += CloseActivity;

			// Indicate to the Workflow runtime that this activity is logically still executing, 
			// even though it will not occupy time on a thread until external input arrives.
			return ActivityExecutionStatus.Executing;
		}

		#endregion // Execute [override]

		#region Event Handlers

		void ProcessQueueItemAvailable( object sender, QueueEventArgs e )
		{
			// The external input has arrived, so wake up and process it.
			WorkflowQueue workflowQueue = this.GetWorkflowQueue( sender as ActivityExecutionContext );
			if( workflowQueue.Count > 0 )
				this.inputText = workflowQueue.Dequeue() as string;
		}

		void CloseActivity( object sender, QueueEventArgs e )
		{
			// The external input has arrived and been processed, so throw away the WorkflowQueue
			// that we used, and tell the Workflow runtime that the activity is finished.
			ActivityExecutionContext executionContext = sender as ActivityExecutionContext;
			WorkflowQueuingService queuingService = executionContext.GetService<WorkflowQueuingService>();
			queuingService.DeleteWorkflowQueue( this.Name );
			executionContext.CloseActivity();
		}

		#endregion // Event Handlers

		#region Private Helpers

		// Helper method which returns a WorkflowQueue.
		WorkflowQueue GetWorkflowQueue( ActivityExecutionContext executionContext )
		{
			WorkflowQueue queue;
			WorkflowQueuingService queuingService = executionContext.GetService<WorkflowQueuingService>();			
			if( queuingService.Exists( this.Name ) )
				queue = queuingService.GetWorkflowQueue( this.Name );
			else
				queue = queuingService.CreateWorkflowQueue( this.Name, true );

			return queue;
		}

		#endregion // Private Helpers
	}

	#endregion // ReadConsoleLine

	#region GreetUser

	/// <summary>
	/// Prints a greeting to the user.
	/// </summary>
	public class GreetUser : Activity
	{
		public static readonly DependencyProperty UserNameProperty;

		static GreetUser()
		{
			UserNameProperty = DependencyProperty.Register( 
				"UserName", 
				typeof( string ), 
				typeof( GreetUser ) );
		}

		// UserName is a dependency property so that it can be bound to the
		// InputText property of the ReadConsoleLine activity.
		public string UserName
		{
			get { return (string)GetValue( UserNameProperty ); }
			set { SetValue( UserNameProperty, value ); }
		}

		protected override ActivityExecutionStatus Execute( ActivityExecutionContext executionContext )
		{
			string greeting = String.Format( "Hello, {0}!", this.UserName );
			Console.WriteLine( greeting );

			return ActivityExecutionStatus.Closed;
		}
	}

	#endregion // GreetUser
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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


Written By
Software Developer (Senior)
United States United States
Josh creates software, for iOS and Windows.

He works at Black Pixel as a Senior Developer.

Read his iOS Programming for .NET Developers[^] book to learn how to write iPhone and iPad apps by leveraging your existing .NET skills.

Use his Master WPF[^] app on your iPhone to sharpen your WPF skills on the go.

Check out his Advanced MVVM[^] book.

Visit his WPF blog[^] or stop by his iOS blog[^].

See his website Josh Smith Digital[^].

Comments and Discussions