Additionally, if you haven't downloaded the modified Northwind database or the SharedAssemblies, you will need to download them at the bottom of the Lesson intropage. (Click me)
(Click on the link and the DB is at the bottom of the lesson.)
Please be sure to modify the app.config file to point to the machine you which you setup restore the database too.
All the assemblies used for the demo are contained in the SharedAssemblies folder so you may need to set your reference paths accordingly.
As with all the lessons, I would like to thank the following:
Telerik for making wonderful RAD controls which make our development lives a lot easier. The Demo versions of 2010 Q1 WPF controls were used and can be found at the Telerik website.
http://www.telerik.com/account/free-trials/single-trial.aspx?pid=601
Their RadRibbonBar is a great control and easy to use. Plus you get nice Theme's right of the box so you don't have to waste unnecessary time creating your own.
A big thanks to Sacha Barber for Cinch, NSVMVVM is a slightly modified version of Sacha's Cinch Framework.
Josh Smith for all his work posted on the internet. Also, for this lesson, Eugene Pankov for his CompositeWPFApp sample.Finally to the others who have taken the time to post helpful work on the internet.
Let's get started. Starting with this lesson we're going to start defining requirements up front and then work our way towards implementing them in our application. Kind of like what we deal with in our everyday development lives.
In Lesson 5, we got our application up and running and populating data. However this week, our "boss" informs us that we need to have the ability for our Ribbonbar to have interchangeable QuickAccessToolBar buttons.
Our requirements are as follows:
1. Have a central RibbonBar control which all of the ApplicationMenu buttons are the same and can be used with any View in any module.
2. The views in any module should populate the QuickAccessToolBar buttons of the central RadRibbonBar.
With these requirements in hand, we start architecting to come up with what it would take to meet these requirements. (Please note, the goal here is not to create the perfect application, but more so get a good working solution together and posted for others to look at, use, pick apart, etc. If you come up with a better way of doing things, please share and we'll all get better.)
We start with requirement 1. When I see the comments "central" & "used any View in any module", I immediately think of the infrastructure assembly.
However, some might break this out and create a separate assembly called UIControls or similiar. You'll notice I did both. I created a folder called Menus in the infrastructure assembly to store the RibbonControl. Then I created a new assembly called resources to have a central place to store the global images. These could very well go in the infrastructure assembly as well.
Now back to the Ribbonbar control. As mentioned above, in the NST.NW.Infrastructure assembly we create a MainRibbonControl.xaml. Per our requirements, we populate our ApplicationMenu with buttons that will be standard throughout the application. The ApplicationMenu is the dropdown that appears when the main RibbonButton is clicked. In Figure 1 one below you'll see that we have Customers & Employee's ribbon buttons.
Figure 1
To wire up the commands for each of the RibbonButtons, we create the GlobalCommands static class where we define RoutedUICommands. These commands will allow us to create entries into the Application's CommandBindings collection. Be sure to initialize these commands in the GlobalCommands constructor.
In order to use these global commands in our MenuRibbonControl.xaml, we'll add a reference to our infrastructure namespace.
xmlns:infrastructure="clr-namespace:NST.NW.Infrastructure"
Then define our command as follows:
<telerikRibbonBar:RadRibbonButton Text="Customers" Command="infrastructure:GlobalCommands.ShowCustomerTempla teCommand"/>
Now we have our GlobalCommands defined but we have initialize them where the logic will reside to handle them when they are called. Since these commands are directly involved with loading our shell templates, we'll do this in the constructor of our ShellViewModel as shown in the following code.
Code:
// Create Menu Bindings CommandBinding _showCustTempBinding = new CommandBinding(GlobalCommands.ShowCustomerTemplateCommand, ShowCustomerCommand_Executed, Command_CanExecute); CommandBinding _showEmployeeTempBinding = new CommandBinding(GlobalCommands.ShowEmployeeTemplateCommand, ShowEmployeeCommand_Executed, Command_CanExecute); Application.Current.MainWindow.CommandBindings.Add(_showCustTempBinding); Application.Current.MainWindow.CommandBindings.Add(_showEmployeeTempBinding);
Per requirement 1, we now have a RibbonBar control with defined ApplicationMenu buttons that can be used in any module.
We need the menu in both our Employee & CustomerView's. In our CustomerView.xaml, we add the same reference to the infrastructure assembly.
xmlns:infrastructure="clr-namespace:NST.NW.Infrastructure;assembly=NST.NW.In frastructure"
Next we implement the MainRibbonControl. Also, here we can satisfy requirement 2 and we define the QuickAccessToolBar buttons needed for the CustomerView.
Code:
<infrastructure:MainRibbonControl x:Name="MainRibbonControl" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" > <telerikRibbonBar:RadRibbonBar.QuickAccessToolBar> <telerikRibbonBar:QuickAccessToolBar> <telerikRibbonBar:RadRibbonButton Text="New" Command="{Binding NewCustomerCommand}" SmallImage="/NST.NW.Resources;component/Images/16/new.png" Size="Small" ToolTip="New Customer" /> <telerikRibbonBar:RadRibbonButton Text="New" Command="{Binding EditCustomerCommand}" SmallImage="/NST.NW.Resources;component/Images/16/Editor.png" Size="Small" ToolTip="Edit Customer" /> <telerikRibbonBar:RadRibbonButton Text="Save" Command="{Binding SaveCustomerCommand}" SmallImage="/NST.NW.Resources;component/Images/16/save.png" Size="Small" ToolTip="Save Customer" IsEnabled="False" /> <telerikRibbonBar:RadRibbonButton Text="New" Command="{Binding ClearChangesCommand}" SmallImage="/NST.NW.Resources;component/Images/16/eraser.png" Size="Small" ToolTip="Cancel Changes" IsEnabled="False" /> </telerikRibbonBar:QuickAccessToolBar> </telerikRibbonBar:RadRibbonBar.QuickAccessToolBar> </infrastructure:MainRibbonControl>
When we run our application, we can see that a separate RadRibbonBar with different QuickAccessToolBar buttons. (You can verify this by hovering the mouse about an image and reading the tool tip.)
So per our requirements, we have a central RibbonBar control that can be used in any module. Also, each view that uses the MainRibbonControl can set its own QuickAccessToolBar buttons.
Thus, that concludes our lesson. If you have any questions or comments, please post them.
P.S. Please note you will need to download both .rar files. The NSTPrismSample is the VS Solution files. The SharedAssemblies.rar contains the shared assemblies used in demo's. Any time a new assembly is introduced, this file will be updated. Please use it with all the lessons going forward.







Section Widget
Categories Widget (top-down)

