Page 1 of 1

Hooking Menu Items to ApplicationCommand's standard set.

#1 StCroixSkipper  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 10
  • View blog
  • Posts: 121
  • Joined: 23-December 08

Posted 30 January 2010 - 12:40 PM

MenuItems define a Click event and a Command property as well as an Icon property of type Object, a Boolean IsChecked property, an IsCheckable and a Checked event. The property that intrigues me here is the Command property.

There is a .Net class called ApplicationCommands which has a set of static properties which provides a standard set of application commands. Here is the list of some of the Commands defined in ApplicatonCommands:
CancelPrint
Close
Copy
Cut
Delete
Find
Help
New
Open
Paste
Print
Redo
Replace
Save
SaveAs
SelectAll
Stop
Undo

These standard commands can easily be hooked up to your MenuItem with just a few lines of C# code.

First, Create a WPF application by clicking File->New->Project... to get the New Project dialog and select Visual C# in the lefthand pane. In the righthand pane select WPF Application, give it an appropriate name and location and click OK.

I usually create a Help folder within the project so in Solution Explorer right click on the project and select Add->New Folder and give it the name 'Help'.

Rightclick on the Help folder and select Add->New Item... to get the Add New Item dialog box. Click on WPF in the lefthand pane and then click on the Window (WPF) template and name it 'HelpWindow' and click the Add button.

Here is the XAML code I added to the Helpwindow.xaml file:

<NavigationWindow x:Class="HelpTutorial.Help.HelpWindow"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	Title="Help Tutorial Help"				  
	Height="600" Width="800"
	ShowInTaskbar="False"
	WindowStartupLocation="CenterScreen"
	Foreground="Blue">
	<Navigationwindow.Content >
		<Grid >
			<Grid.ColumnDefinitions>
				<ColumnDefinition Width="25*" />
				<ColumnDefinition Width="Auto" />
				<ColumnDefinition Width="75*" />
			</Grid.ColumnDefinitions>

			<TreeView Name="tree" FontSize="10pt" 
					  SelectedItemChanged="HelponselectedItemChanged"
					  >
				<TreeViewItem Header="Program Overview" 
						  Tag="Help/Overview.xaml" />

				<TreeViewItem Header="Exploring the Menus" >
				<TreeViewItem Header="The File Menu"/>

				<TreeViewItem Header="The Edit Menu"/>

				<TreeViewItem Header="The Stylus-Mode Menu"/>

				<TreeViewItem Header="The Eraser-Mode Menu"/>

				<TreeViewItem Header="The Tools Menu"/>

				<TreeViewItem Header="The Help Menu"/>
				-->
				</TreeViewItem>
				<TreeViewItem Header="Copyright Information" 
						  Tag="Help/HelpAbout.xaml" />
			</TreeView>

			<GridSplitter Grid.Column="1" Width="6" 
						  HorizontalAlignment="Center" 
						  VerticalAlignment="Stretch" />

			<Frame Name="frame" Grid.Column="2" />
		</Grid>
	</Navigationwindow.Content>
</NavigationWindow>



Notice that I changed 'Window' to 'NavigationWindow'. NavigationWindows are interesting by themselves. NavigationWindow derives from Window, so it does everything a Window does and it adds the ability to 'navigate' or go forward to the next page or back to the previous page like the forward and back arrows in Internet Explorer's menu bar.

To hook this help window up to the 'Help' command defined in ApplicationCommands simply add these two functions to the 'Window1.xaml.cs' file or whatever you've called your main window.

		private void HelpCanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = true;
		}

		void HelpOnExecuted(object sender, ExecutedRoutedEventArgs args)
		{
			HelpWindow win = new HelpWindow();
			win.Owner = this;
			win.Show();
		}



And Add a DockPanel to your main window's xaml file to contain the Help menu.

Here is the XAML code for my main window:

<Window x:Class="HelpTutorial.Window1"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	Title="Help Tutorial" Height="300" Width="300">
	<DockPanel>
		<DockPanel DockPanel.Dock="Top" HorizontalAlignment="Stretch" Background="AliceBlue">
			<Menu HorizontalAlignment="Right" Width="60">
				<!-- Help Menu. -->
				<MenuItem Header="Help" Width="60" HorizontalAlignment="Center">
					<MenuItem Header="_Help" Command="Help"/>
					<MenuItem Header="_About" Click="Aboutonclick"/>
				</MenuItem>
			</Menu>
		</DockPanel>
	</DockPanel>
	<!-- Accumulate all the command binding objects -->
	<[b]window.CommandBindings[/b]>
		<[b]CommandBinding Command="Help" Executed="HelpOnExecuted" CanExecute="HelpCanExecute"/>
	</window.CommandBindings[/b]>
</Window>



Notice the 'Accumulate all the command binding objects section at the bottom. Here you'll see the 'HelpOnExecuted' and 'CanExecute' values that point to the two functions we added. These XAML lines hook the MenuItem to the functions that provide the behavior we want.

To make this a little more interesting, you'll also notice that references to HelpAbout.xaml and Overview.xaml. I simply right clicked on the Help folder and selected the Add->New Item... to get the New Item dialog box and selected the Page (WPF) template, gave it the names HelpAbout.xaml and Overview.xaml respectively.

Here is the xaml code for these files.
<Page x:Class="HelpTutorial.Help.Overview"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	Title="Overview"
	Foreground="Blue">
	<FlowDocumentReader ViewingMode="Scroll">
		<FlowDocument>
			<Paragraph TextAlignment="Center"
					   FontSize="16pt">
				<Bold>IN CONGRESS, JULY 4, 1776</Bold>
			</Paragraph>
			<Paragraph TextAlignment="Center"
					   FontSize="16pt">
				<Bold>The unanimous Declaration of the thirteen united States of America</Bold>
			</Paragraph>
			<Paragraph>
				When in the Course of human events it becomes necessary for one people to 
				dissolve the political bands which have connected them with another and to 
				assume among the powers of the earth, the separate and equal station to 
				which the Laws of Nature and of Nature's God entitle them, a decent 
				respect to the opinions of mankind requires that they should declare the 
				causes which impel them to the separation.
			</Paragraph>
			<Paragraph >
				We hold these truths to be self-evident, that all men are created equal, 
				that they are endowed by their Creator with certain unalienable Rights, 
				that among these are Life, Liberty and the pursuit of Happiness.  That 
				to secure these rights, Governments are instituted among Men, deriving 
				their just powers from the consent of the governed,  That whenever any 
				Form of Government becomes destructive of these ends, it is the Right of 
				the People to alter or to abolish it, and to institute new Government, 
				laying its foundation on such principles and organizing its powers in 
				such form, as to them shall seem most likely to effect their Safety and 
				Happiness. Prudence, indeed, will dictate that Governments long established 
				should not be changed for light and transient causes; and accordingly all 
				experience hath shewn that mankind are more disposed to suffer, while evils 
				are sufferable than to right themselves by abolishing the forms to which 
				they are accustomed. But when a long train of abuses and usurpations, 
				pursuing invariably the same Object evinces a design to reduce them under 
				absolute Despotism, it is their right, it is their duty, to throw off such 
				Government, and to provide new Guards for their future security.  Such 
				has been the patient sufferance of these Colonies; and such is now the 
				necessity which constrains them to alter their former Systems of Government. 
				The history of the present King of Great Britain is a history of repeated 
				injuries and usurpations, all having in direct object the establishment 
				of an absolute Tyranny over these States. To prove this, let Facts be 
				submitted to a candid world.
			</Paragraph>
			<Paragraph>
				1. He has refused his Assent to Laws, the most wholesome and necessary for 
				the public good.
			</Paragraph>
			<Paragraph>
				2. He has forbidden his Governors to pass Laws of immediate and pressing 
				importance, unless suspended in their operation till his Assent should be 
				obtained; and when so suspended, he has utterly neglected to attend to them.
			</Paragraph>
			<Paragraph>
				3. He has refused to pass other Laws for the accommodation of large 
				districts of people, unless those people would relinquish the right 
				of Representation in the Legislature, a right inestimable to them and 
				formidable to tyrants only.
			</Paragraph>
			<Paragraph >
				4. He has called together legislative bodies at places unusual, 
				uncomfortable, and distant from the depository of their Public 
				Records, for the sole purpose of fatiguing them into compliance 
				with his measures.
			</Paragraph>
			<Paragraph>
				5. He has dissolved Representative Houses repeatedly, for opposing 
				with manly firmness his invasions on the rights of the people.
			</Paragraph>
			<Paragraph>
				6. He has refused for a long time, after such dissolutions, to cause others 
				to be elected, whereby the Legislative Powers, incapable of Annihilation, 
				have returned to the People at large for their exercise; the State remaining 
				in the mean time exposed to all the dangers of invasion from without, and 
				convulsions within.
			</Paragraph>
			<Paragraph>
				7. He has endeavoured to prevent the population of these States; for that 
				purpose obstructing the Laws for Naturalization of Foreigners; refusing to 
				pass others to encourage their migrations hither, and raising the conditions 
				of new Appropriations of Lands.
			</Paragraph>
			<Paragraph>
				8. He has obstructed the Administration of Justice by refusing his Assent 
				to Laws for establishing Judiciary Powers.
			</Paragraph>
			<Paragraph>
				9. He has made Judges dependent on his Will alone for the tenure of their 
				offices, and the amount and payment of their salaries.
			</Paragraph>
			<Paragraph>
				10. He has erected a multitude of New Offices, and sent hither swarms 
				of Officers to harass our people and eat out their substance.
			</Paragraph>
			<Paragraph>
				11. He has kept among us, in times of peace, Standing Armies without 
				the Consent of our legislatures.
			</Paragraph>
			<Paragraph>
				12. He has affected to render the Military independent of and superior to 
				the Civil Power. 
			</Paragraph>
			<Paragraph>
				Click on
				<Hyperlink NavigateUri="http://www.ushistory.org/declaration/document/index.htm">
					Declaration of Independence
				</Hyperlink>
				for more information.
			</Paragraph>
		</FlowDocument>
	</FlowDocumentReader>
</Page>



<Page x:Class="HelpTutorial.Help.HelpAbout"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	Title="HelpAbout"
	Foreground="Blue"
	Width="520"
	Height="530"
	>
	<FlowDocumentReader ViewingMode="Scroll">
		<FlowDocument>
			<Paragraph TextAlignment="Center"
					   FontSize="16pt">
				Copyright Information
			</Paragraph>
			<Paragraph TextAlignment="Center" 
					   FontSize="12pt">
				 2009 by Windward Rail Software
			</Paragraph>
			<BlockUIContainer>
				<Image Source="/Images/SuspendedAnimation.png" Width="500" />
			</BlockUIContainer>
		</FlowDocument>
	</FlowDocumentReader>
</Page>



Only one thing left to do. In the HelpAbout.xaml file I've referenced a picture, <Image Source="/Images/SuspendedAnimation.png" Width="500" /> in the <BlockUIContainer></BlockUIContainer> element.

Right click on the project, select the Add->New Folder menu item and name the new folder Images. Then copy the attacted 'png' file or provide one of your own to the Images folder and add it to the project.

I've included the picture I used but you can choose your own. In this case, it a picture of me and 12 young men (Explorer Scouts) I took on a weeklong cruise of Chesapeake Bay on my Express 37 sailboat, Suspended Animation. We went from Annopolis to Baltimore, anchored in the harbor, took the water taxi in to see an Orioles game and spent the night on the hook in the harbor. The next morning we sailed out of Baltimore harbor, out past Fort McHenry and spent the week cruising the interesting places in the area.



You may wonder where my user name came from. I'm love to sail. I've frequently chartered bareboats from Anacortes, WA, Boston, MA and the U.S. and British Virgin Islands. One of my favorite destinations is St. Croix, hence StCroixSkipper.

Say what you will, I think WPF is great.

Is This A Good Question/Topic? 0
  • +

Page 1 of 1