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

( WPF, XAML, C# ) WITIYMIWYG - What Is There In Your Mind Is What You Get - Wizard. - In English and Kannada, With Simple Animations.

0.00/5 (No votes)
29 Oct 2008 1  
( WPF, XAML, C# ) WITIYMIWYG - What Is There In Your Mind Is What You Get - Wizard. - Is the Mind Reader Application with Simple Animations and Multi Language Support English and Kannada.

Sample Image - maximum width is 600 pixels

Content

Introduction

WITIYMIWYG - What Is There In Your Mind Is What You Get. Is a Multi Language Support (English and Kannada) Wizard, The Wizard has 4 Steps/Screens. It is a Kind of Mind Reader, It will ask you 3 simple and similar questions and based on that it will display what is there in your mind. In this example I have used 21 Heart Images. We can use any kind of Images, Numbers and String etc... But the Base Concept is the same.

WITIYMIWYG - What Is There In Your Mind Is What You Get - Core Concept

What Is There In Your Mind Is What You Get - 21 Heart Images will be displayed. in 3 rows

1 to 7 in first Row

8 to 14 in second Row

15 to 21 in third Row

Step A

Sample Image - maximum width is 600 pixels

We can have either row or column doesn’t matter, In this example I have used rows. then ask the user to select in which row his selected heart image exist.

Step B

If the user select 3rd row then take the third row and insert in between 1st or 2nd row (so that it can appear in middle).

Sample Image 
  - maximum width is 600 pixels

Step C

Take each item and split it into 3 rows one by one. First item in first row, Second item in second row, third item in third row, 4th item in first row and so on... till the last item.

Sample Image - maximum width is 600 pixels

I have shown the example for one cycle, repeat the steps for Total 3 cycle, which ever row user select place it in middle, in case if user select middle row then just follow Step B and Step C. After 3d Cycle Complete then take the 2nd Row 4th Item or in 3d Cycle Step B take the 11th Item. This is what is there in your mind/what you have thought. Display the item to the user what he has thought.

How does it work?, when ever we place the selected row in between other two rows, the item may appear in first row 4th or 5th order or in second row 3rd,4th or 5th order or in the third row 3rd or 4th order. During the 3rd Cycle, what is there in our mind item will always occupy the middle row and middle item. So that we can display to the user what he has thought.

Wizard Steps

The wizard has 4 Screens.

1) Language Selection Screen

Select the Language English or Kannada, the above displayed screen is the first screen in the wizard.

2) Introduction Screen

This Screen will give the Introduction of the Application.

In English

Sample Image - maximum width is 600 pixels

In Kannada

Sample Image - maximum width is 600 pixels

3) Show Screen

This Screen will show you 3 questions and ask you to answer on the same screen. Once all the 3 questions are answered it will take the user to next screen.

In English

Sample Image - maximum width is 600 pixels

In Kannada

Sample Image - maximum width is 600 pixels

4) You Thought Screen

This Screen will show exactly the same Heart Image what you remembered.

In English

Sample Image - maximum width is 600 pixels

In Kannada

Sample Image - maximum width is 600 pixels

How To Setup PC To Support Indian Languages

First thing before we start any Multi Language Application, we have to check our PC Supports it, if not we can setup, for Indian Language Support we have Install Indic, it requires OS Setup Disk I386 Folder Contents.

Non Supported PC

The Non Supported PC will display the Junk Characters if you open the Resource file and enter the desired language text.

Sample Image - maximum width is 600 pixels

Even if we have same resource file with junk character during executing program if we want to Fetch/Bind/Display the same we get the junk chars only.

Sample Image - maximum width is 600 pixels
 
In this case we need to go to Control Panel and Select Regional and Language Options.
Sample Image - maximum width is 600 pixels

And go to Language Tab. And Click on the Checkbox "Install files for Complex Script...."

Sample Image - maximum width is 600 pixels

You will get the following Popup Message Titled "Install Supplemental Language Support" Click on [OK] this includes Complex (Indic) which enable Indian languages. For more info follow link [here] And Click on [Apply] Button on the above Displayed Dialog, you need to have OS Setup CD, Browse and Select the I386 Folder and Proceed...

After Successful Installation, you will get a popup to restart the system, Restart the System. Now your System will support Indian languages.

Supported PC



In Supported PC you can view the Language Text Correctly, if you open visual studio resource editor. You can see the correct language text here I am showing the same example, above screen earlier it displayed junk chars now it is showing correctly after setup.

Sample Image - maximum width is 600 pixels

Now If we fetch/bind/display the data we get it in correct format and right characters are displayed.

Sample Image - maximum width is 600 pixels

Project File

When we open the code behind files in Expression Blend for the first time if you have vs2008 as default we get the conversion wizard after conversion the project file gets altered. but if you want your expression blend 1 .csproj file to open in vs2008/vs2005 with minimum changes in .csproj file and also to refer the 3.5 version in expression blend 1 project(by default it refers 3.0 framework).  Open the .csproj file in text editor. and just add a Tools Version in the project Tag. example <Project ToolsVersion="3.5" ...> and if you want to include project reference you can include as shown in the Example <Reference Include="System.Core" />. If you open it in vs2005 for the first time you will get Security Warning for [Project Name] dialog, just Select Load project normally and click on [OK] button. Please follow the link [here] for more info.

Runtime Globalization

This Wizard uses Runtime Globalization, languages are decided during runtime. to do this first we need to have resource files. one of the resource will be the default resource file in which auto generated code behind file needed, in visual studio 2008 it generates the code behind file. for example if we have default file as Resource.resx which has default language en - for English, the code behind files will be Resource.resx.cs which will have auto generated code. In the resource editor go and set the Access Modifier to "Internal" then add one more Resource file for the other language. Just keep the same "Resource" file name before first dot and then add the language code with dot before file extinction for example if I want to add Kannada Language which has code kn or kn-In I can rename to Resource.kn.resx and in the resource editor change the Access Modifier to "No Code Generation" and save it, each Resource file does not require Code Generation when it has same file name before first dot. Please follow the link [here] for other culture/language code.

Sample Image - maximum width is 600 pixels

Create a Properties Folder from solution explorer if not exist then move the Resource files to that Properties folder.

Sample Image - maximum width is 600 pixels

Note: both the resource files should have the same Key Names.

In this Application I have used the key names called Title, SplashEnglish, SplashKannada, Intro, OnceMore, Proceed, Questions, YouThought. I have used the same Key Names in both the files Resource.resx and Resource.kn.resx, so that when I change the language culture I can access the values from the same KeyNames. for Example if the culture is en during runtime and if I use Properties.Resource.OnceMore it will return OnceMore key value in English from Resource.resx file, if I change the culture to kn then if I use Properties.Resource.OnceMore it will return Kannada Value from Resource.kn.resx file.

English Resource

Sample Image - maximum width is 600 pixels

Kannada Resource

Sample Image - maximum width is 600 pixels

How to Make a Spinning Star Animated Button

I have used 2 very simple animations in this Application

1) Spinning Star Animation
2) Expanding Mat Animation.

To make spinning star animation button, In Microsoft Expression Blend go to file->New and select the installed template User Control

Sample Image - maximum width is 600 pixels

Set the following attributes to User Control Tag Width="48" Height="40" Cursor="Hand" Add the Star Image to the Project By Right Click on the Project -> Add Existing Item. Then browse and select the star image. After adding it to project double clicks on the image in solution explorer. It will appear on the user control, resize it as shown in the image below.

Sample Image - maximum width is 600 pixels

As shown on the above image select the image and create new timeline. Then you will get the timeline dialog. Click on [OK].

Sample Image - maximum width is 600 pixels

Then Select the Image and Create/Click on the Record Key Frame.

Sample Image - maximum width is 600 pixels

Then Pull/Drag the Yellow Time Line to 2 Seconds. And Just Hold the Bottom Right Corner Image Handle and Rotate clock wise for one complete round.

Sample Image - maximum width is 600 pixels

You can see the Record Key Frame is now created at 2 Seconds where yellow time line exist and also smoke white line joining this two Record Key Frames.

Sample Image - maximum width is 600 pixels

Now if you play the star will spin only once, so how to make the star spin continuously. In the object and timeline Image Drill down Expand the Image Animations till the last drill down Angle. As shown in the image below and then right click on it you will get the popup menu - Select Edit Repeat Count.

Sample Image - maximum width is 600 pixels

Click on Infinite/Forever Button and click on [OK] in the popup dialog. This will make the star spin for ever.

Sample Image - maximum width is 600 pixels

How to pause the animation spinning star when mouse down. And resume the spinning star animation when mouse is up? Go to Triggers section first and click on add event. And select the when user control loaded event is raised select the timeline1.begin this will start the animation when control is loaded. (Note in the image all the 3 triggers are displayed I am explaining one by one)

Sample Image - maximum width is 600 pixels

Then add mouse down event and select the timeline to pause. So that when ever the mouse down occurs on user control it will pause the spinning star.

Sample Image - maximum width is 600 pixels

Then add mouse up event and select the timeline to Resume. So that when ever the mouse up occurs on user control it will Resume the spinning star.

Sample Image - maximum width is 600 pixels

Now Build the project, after successful build, the control will appear in asset library on the toolbox and select custom control tab.

Sample Image - maximum width is 600 pixels

Drag and Drop the StarButton on the Window Form. To handle the event of that star button go to events and write the event handler for MouseLeftButtonUp.

Sample Image - maximum width is 600 pixels

Layers

There are 5 layers in this application, at a time any one layer will be visible except LayerMat which i used for animation which appears over LayerShow. LayerSplash is the first screen in the WITIYMIWYG Wizard, LayerIntro is the 2nd Screen in the WITIYMIWYG Wizard which gives introduction, LayerShow is the 3rd screen in the WITIYMIWYG Wizard which shows all 21 heart images. LayerMat is the animation Layer which will appear on top of the LayerShow to hide the 21 heart images by displaying animation when user click on spinning star button. LayerEnd is the Last screen shown to the user what heart image he has thought.

Sample Image - maximum width is 600 pixels

Mat Expandable Animation with Event Handling

MatExpandedRuntime.PNG

The above image shows mat fully expanded when user has clicked any one of the start button, Mat will expand from the center of displayed 21 heart images with very small or invisible appearance and it will expand both the side’s right and left and it will cover all 21 images. At this time in the background shuffle will take place for 21 heart images and then again it will collapse and come to the same small appearance in the center and disappear. You can also notice when user has answered the below question green tick mark is appearing before each question.


Mat Expandable Animation is created on the LayerMat as explained above, Add 3 Vertical Rectangles/vertical bars and then add one Heart Image, 2 rectangles will move on two sides one in right side from center and other will move left side from center. And one rectangle will just expand both the sides right and left from the center. Place the heart image in center and reduce it to very small size. in below shown image there are 3 vertical bars/rectangles two are in front one is at the back and that is not visible in the image. All are same size.

Sample Image - maximum width is 600 pixels


This is the very simplest animation, how to create timeline and record key frame please see above, come to timeline1 and then Pull/Drag the Yellow Time Line to 3 Seconds Only. And just pull/move the left hand side rectangle to left side desired location and pull/move the right side rectangle to right side same distance as what you have move left and side. And then the middle rectangle will be visible just expand the rectangle so that it touches both the right and left rectangles. and also expand the heart image size. And play the animation and check. You can notice some black color rectangles additional, those are Stroke Thickness when you expand even Stroke Thickness will get expanded. If you want you can set Stroke Thickness to 0 in the properties.

Sample Image - maximum width is 600 pixels


Once Mat Expanded we need to trap the event so go to the xaml editor and set any one of the double animation duration to 4 seconds. And trap CurrentStateInvalidated event in any other double animation which has less time then 4 seconds. In this case all other double animation has 3 seconds choose any one of the double animation in that. When the all the animations are executing in the same timeline up to 3 seconds one animation will further go up to 4 seconds even though its key time is 3 seconds. During this time the remaining double animations will raise the CurrentStateInvalidated becaue it will be idle in the storyboard, so trap this event. And swap the heart images. Here we have used CurrentStateInvalidated="animation1StateInvalidated" there is one more event highlighted CurrentStateInvalidated="parentTimelineStateInvalidated" assigned to story board. When all the animations under story board is complete this event will trigger. This happens when the animation cycle is complete in this Scenario.

Now the Mat Animation is expanded we need to bring it to same state/collapse it as earlier we have to set the AutoReverse="True" in the storyboard so that it will completely reverse all the animations in it. For better Understanding of Animation events please follow the link [here] and [here].

Sample Image - maximum width is 600 pixels


In Designer how it looks.

Sample Image - maximum width is 600 pixels

Cube

I have used 3D Cube to display the What is there in your mind heart image, For more understanding of 3D Cube please follow the link [here], [here] and [here].

Code Behind

I have explained some of the important methods in this application, when ever the user select the language on the first screen the culture is set during run time. based on the language selection. this.Title = Properties.Resource.Title; this code will set the Title Text of the window by fetching from resx file based on culture selection.

private void lblKannada_MUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
	LayerSplash.Visibility = Visibility.Hidden;
	LayerIntro.Visibility = Visibility.Visible;

	string culture = "kn";
	CultureInfo ci = new System.Globalization.CultureInfo(culture);
	System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
	this.Title = Properties.Resource.Title;
	this.lblIntro.Content = Properties.Resource.Intro;
	this.lblProceed.Content = Properties.Resource.Proceed;
}
private void lblEnglish_MUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
	LayerSplash.Visibility = Visibility.Hidden;
	LayerIntro.Visibility = Visibility.Visible;

	string culture = "en";
	CultureInfo ci = new System.Globalization.CultureInfo(culture);
	System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
	this.Title = Properties.Resource.Title;
	this.lblIntro.Content = Properties.Resource.Intro;
	this.lblProceed.Content = Properties.Resource.Proceed;

}	
ArrangeHeartImages()Method will set the positions of the display heart images.Row1Selected();Row2Selected();Row3Selected(); these are the method which place the selected row in the middle and swaps the image positions in hash table collections based on the rotating star button click.

private void ArrangeHeartImages()
{
	int j = 0;
	int k;
	myHashAllControls.Clear();

	myHashRow1.Clear();
	myHashRow2.Clear();
	myHashRow3.Clear();
	foreach (UIElement uie in CanvasImages.Children)
	{
		Image im = uie as Image;
		if (im != null)
		{
			if (im.Name.StartsWith("_"))
			{
				k = int.Parse(im.Name.Substring(1, im.Name.Length - 1));
				if (k < 8)
				{
					j = k - 1;
					Canvas.SetTop(im, (int)HeartRows.Row1);
					Canvas.SetLeft(im, RowLeftStart + (j * RowLeftIncrement));
					myHashAllControls.Add(im.Name, im);
					myHashRow1.Add(j, im.Name);
				}
				else if ((k >= 8) && (k < 15))
				{
					j = k - 8;
					Canvas.SetTop(im, (int)HeartRows.Row2);
					Canvas.SetLeft(im, RowLeftStart + (j * RowLeftIncrement));
					myHashAllControls.Add(im.Name, im);
					myHashRow2.Add(j, im.Name);
				}
				else if ((k >= 15) && (k < 22))
				{
					j = k - 15;
					Canvas.SetTop(im, (int)HeartRows.Row3);
					Canvas.SetLeft(im, RowLeftStart + (j * RowLeftIncrement));
					myHashAllControls.Add(im.Name, im);
					myHashRow3.Add(j, im.Name);
				}
			}
		}
	}

}

private void Row1Selected()
{
	// for first row button click 
	int i;
	int j = 0;
	myHashAllRows.Clear();

	//second row
	for (i = 0; i < 7; i++)
	{
		myHashAllRows.Add(j, myHashRow2[i]);
		j++;
	}
	//First row
	for (i = 0; i < 7; i++)
	{
		myHashAllRows.Add(j, myHashRow1[i]);
		j++;
	}
	//third row
	for (i = 0; i < 7; i++)
	{
		myHashAllRows.Add(j, myHashRow3[i]);
		j++;
	}

	myHashRow2.Clear();
	myHashRow1.Clear();
	myHashRow3.Clear();
	Image R1;
	Image R2;
	Image R3;
	j = 0;
	for (i = 0; i < 7; i++)
	{
		R1 = GetImageControlByName((string)myHashAllRows[j]);
		Canvas.SetTop(R1, (int)HeartRows.Row1);
		Canvas.SetLeft(R1, RowLeftStart + (RowLeftIncrement * i));
		myHashRow1.Add(i, R1.Name);

		R2 = GetImageControlByName((string)myHashAllRows[j + 1]);
		Canvas.SetTop(R2, (int)HeartRows.Row2);
		Canvas.SetLeft(R2, RowLeftStart + (RowLeftIncrement * i));
		myHashRow2.Add(i, R2.Name);

		R3 = GetImageControlByName((string)myHashAllRows[j + 2]);
		Canvas.SetTop(R3, (int)HeartRows.Row3);
		Canvas.SetLeft(R3, RowLeftStart + (RowLeftIncrement * i));
		myHashRow3.Add(i, R3.Name);
		j = j + 3;
	}
}
private void Row2Selected()
{
	// for Second row button click 
	int i;
	int j = 0;
	myHashAllRows.Clear();

	//First row
	for (i = 0; i < 7; i++)
	{
		myHashAllRows.Add(j, myHashRow1[i]);
		j++;
	}
	//Second row
	for (i = 0; i < 7; i++)
	{
		myHashAllRows.Add(j, myHashRow2[i]);
		j++;
	}
	//third row
	for (i = 0; i < 7; i++)
	{
		myHashAllRows.Add(j, myHashRow3[i]);
		j++;
	}

	myHashRow1.Clear();
	myHashRow2.Clear();
	myHashRow3.Clear();
	Image R1;
	Image R2;
	Image R3;
	j = 0;
	for (i = 0; i < 7; i++)
	{
		R1 = GetImageControlByName((string)myHashAllRows[j]);
		Canvas.SetTop(R1, (int)HeartRows.Row1);
		Canvas.SetLeft(R1, RowLeftStart + (RowLeftIncrement * i));
		myHashRow1.Add(i, R1.Name);

		R2 = GetImageControlByName((string)myHashAllRows[j + 1]);
		Canvas.SetTop(R2, (int)HeartRows.Row2);
		Canvas.SetLeft(R2, RowLeftStart + (RowLeftIncrement * i));
		myHashRow2.Add(i, R2.Name);

		R3 = GetImageControlByName((string)myHashAllRows[j + 2]);
		Canvas.SetTop(R3, (int)HeartRows.Row3);
		Canvas.SetLeft(R3, RowLeftStart + (RowLeftIncrement * i));
		myHashRow3.Add(i, R3.Name);
		j = j + 3;
	}

}
private void Row3Selected()
{
	// for Third row button click 
	int i;
	int j = 0;
	myHashAllRows.Clear();

	//First row
	for (i = 0; i < 7; i++)
	{
		myHashAllRows.Add(j, myHashRow1[i]);
		j++;
	}
	//Three row
	for (i = 0; i < 7; i++)
	{
		myHashAllRows.Add(j, myHashRow3[i]);
		j++;
	}
	//Two row
	for (i = 0; i < 7; i++)
	{
		myHashAllRows.Add(j, myHashRow2[i]);
		j++;
	}

	myHashRow1.Clear();
	myHashRow3.Clear();
	myHashRow2.Clear();
	Image R1;
	Image R2;
	Image R3;
	j = 0;
	for (i = 0; i < 7; i++)
	{
		R1 = GetImageControlByName((string)myHashAllRows[j]);
		Canvas.SetTop(R1, (int)HeartRows.Row1);
		Canvas.SetLeft(R1, RowLeftStart + (RowLeftIncrement * i));
		myHashRow1.Add(i, R1.Name);

		R2 = GetImageControlByName((string)myHashAllRows[j + 1]);
		Canvas.SetTop(R2, (int)HeartRows.Row2);
		Canvas.SetLeft(R2, RowLeftStart + (RowLeftIncrement * i));
		myHashRow2.Add(i, R2.Name);

		R3 = GetImageControlByName((string)myHashAllRows[j + 2]);
		Canvas.SetTop(R3, (int)HeartRows.Row3);
		Canvas.SetLeft(R3, RowLeftStart + (RowLeftIncrement * i));
		myHashRow3.Add(i, R3.Name);
		j = j + 3;
	}
}

Event Handlers for Star Button Click will Start the Mat Animation.
private void StarOneUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
	ShowQuestImages();
	HideStarButtons();
	SelectedRowStar = 1;
	LayerMat.Visibility = Visibility.Visible;
	Storyboard sb = LayerMat.TryFindResource("Timeline1") as Storyboard;
	sb.Begin(LayerMat);
}
Mat Animation Invalid State Event Handlers, in this parentTimelineStateInvalidated the mat animation is played 3 times when the user answers the 3 questions. Here it is checked when the 3rd question is answered it will show the next screen. In event handler animation1StateInvalidated when the mat animation is fully expanded and only one of the animation goes for 1 extra second and all other animations will raise CurrentStateInvalidated in the story board at this time the image swapping is done.

private void parentTimelineStateInvalidated(object sender, EventArgs args)
{
	Clock myClock = (Clock)sender;
	if (myClock.CurrentState.ToString() == "Filling")
	{
		LayerMat.Visibility = Visibility.Hidden;
		ShowStarButtons();
		Image im = (Image)myQuest[2];
		if (im.Visibility == Visibility.Visible)
		{
			this.lblOnceMore.Content = Properties.Resource.OnceMore;
			this.lblYouThought.Content = Properties.Resource.YouThought;
			this.lblOnceMore.Visibility = Visibility.Visible;
			this.imgOnceMore.Visibility = Visibility.Visible;

		}

	}
}
private void animation1StateInvalidated(object sender, EventArgs args)
{
	Clock myClock = (Clock)sender;
	if (myClock.CurrentState.ToString() == "Filling")
	{
		this.lblOnceMore.Visibility = Visibility.Hidden;
		this.imgOnceMore.Visibility = Visibility.Hidden;
		if (SelectedRowStar == 1)
			Row1Selected();
		else if (SelectedRowStar == 2)
			Row2Selected();
		else if (SelectedRowStar == 3)
			Row3Selected();

		Image im = (Image)myQuest[2];
		if (im.Visibility == Visibility.Visible)
		{
			ShowMindImage((string)myHashRow2[3]);
			LayerShow.Visibility = Visibility.Hidden;
			LayerEnd.Visibility = Visibility.Visible;
			this.lblYouThought.Content = Properties.Resource.YouThought;
			this.lblOnceMore.Content = Properties.Resource.OnceMore;
		}
	}
}

Conclusion

I have shown the example of Mind Reader (WITIYMIWYG), Covered Simple Spinning Star Animation Control, and Simple Mat Animation with Event Handling during animation execution, Runtime Globalization.

Note - First time when you open the project, build the project so that the control will get referenced in the Display XAML Window.


Thank You, Enjoy Madi!

History

Initial Posting 31st October 2008

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