Welcome to the fifth tutorial in my series of tutorials about the Telerik CAB Enabling Kit. This week, we will learn how to use the RadPanelBar UIExtensionSite. I will be using a TCEK enabled smart client application as the base for this tutorial. I’ve also created a simple module called the Asset Manager module that I will use in this tutorial.
The asset manager module is a basic CAB module that contains one view, the AssetListing view. The AssetListing view contains a RadGridView bound to a list of asset business objects. The business object, called “Asset”, contains properties pertaining to the name, description, and amount of an asset. The AssetListing view also contains two CommandHandlers. The first command handler adds rows to the RadGridView, the second removes rows.
/// <summary>
/// Command handler for adding a new asset to the RadGridView.
/// </summary>
[CommandHandler(CommandNames.AddNewAsset)]
public
void
AddNewAsset(
object
sender, EventArgs e)
{
Asset newAsset =
new
Asset();
newAsset.Name =
"New Asset"
;
View.AssetBindingSource.Add(newAsset);
// Invoke the status update event to notify the status bar that an asset has been added
OnStatusUpdate(
new
EventArgs<
string
>(
"Added new asset..."
));
}
/// <summary>
/// Command handler for removing assets from the RadGridView.
/// </summary>
[CommandHandler(CommandNames.DeleteSelectedAsset)]
public
void
DeleteSelectedAsset(
object
sender, EventArgs e)
{
if
(View.AssetBindingSource.Current !=
null
)
{
View.AssetBindingSource.Remove(View.AssetBindingSource.Current);
}
// Invoke the status update event to notify the status bar that an asset has been deleted
OnStatusUpdate(
new
EventArgs<
string
>(
"Deleted asset..."
));
}
To add the RadPanelBar as a UIExtensionSite, the first step I took was to simply drag a RadPanelBar onto the ShellLayoutView.cs form. Inside the code-behind I've added a property to the RadPanelBar so that I could access it from the presenter.
internal
RadPanelBar MainRadPanelBar
{
get
{
return
_mainRadPanelBar; }
}
In the Infrastructure.Interface project, in the UIExtensionSiteNames.cs file, I added a new string name constants for the UIExtensionSite to use.
./// <summary>
/// The extension site for the main panel bar.
/// </summary>
public
const
string
MainPanelBar =
"MainPanelBar"
;
In the ShellLayoutViewPresenter.cs file, I updated the OnViewSet() method to register the RadPanelBar as a UIExtensionSite.
protected
override
void
OnViewSet()
{
WorkItem.UIExtensionSites.RegisterSite(UIExtensionSiteNames.MainMenu, View.MainMenuStrip);
WorkItem.UIExtensionSites.RegisterSite(UIExtensionSiteNames.MainStatus, View.MainStatusStrip);
WorkItem.UIExtensionSites.RegisterSite(UIExtensionSiteNames.MainToolbar, View.MainToolbarStrip);
// Register the RadPanelBar as a UIExtensionSite
WorkItem.UIExtensionSites.RegisterSite(UIExtensionSiteNames.MainPanelBar, View.MainRadPanelBar);
}
In the AssetManager module’s ModuleController.cs file, I’ve extended the base set of methods to include an ExtendPanelBar() method that gets called from the Run() method. Also, I’ve changed the order of calls in the Run() method as to allow the views to be loaded first.
public
override
void
Run()
{
AddServices();
AddViews();
// load views first
ExtendMenu();
ExtendToolStrip();
ExtendPanelBar();
// extend the panel bar
}
In the ExtendPanelBar() method I've extended the PanelBar UIExtensionSite in two separate ways. The first way uses a standard RadPanelBarGroupElement that contains some button elements used to invoke the commands. The second way actually uses a RadPanelBarGroupElement thats been set up as a host control. The control I've chosen to host in it actually contains another RadGridView that is bound to the same datasource as the AssetListing view.
private
void
ExtendPanelBar()
{
// *** Setup a Regular RadPanelBarGroupElement
// Create the RadPanelBarGroupElement
RadPanelBarGroupElement optionsGroup =
new
RadPanelBarGroupElement();
optionsGroup.Caption =
"Edit Options"
;
this
.WorkItem.UIExtensionSites[UIExtensionSiteNames.MainPanelBar].Add<RadPanelBarGroupElement>(optionsGroup);
// Add buttons to the RadPanelBarGroupElement
RadButtonElement addAssetButton =
new
RadButtonElement(
"Add Asset"
);
this
.WorkItem.Commands[CommandNames.AddNewAsset].AddInvoker(addAssetButton,
"Click"
);
optionsGroup.Items.Add(addAssetButton);
RadButtonElement removeAssetButton =
new
RadButtonElement(
"Remove Asset"
);
this
.WorkItem.Commands[CommandNames.DeleteSelectedAsset].AddInvoker(removeAssetButton,
"Click"
);
optionsGroup.Items.Add(removeAssetButton);
// *** Setup a Host Control RadPanelBarGroupElement
// Create the RadPanelBarGroupElement
RadPanelBarGroupElement hostGroup =
new
RadPanelBarGroupElement();
hostGroup.Caption =
"Navigation Grid"
;
hostGroup.EnableHostControlMode =
true
;
// Add custom gridUserControl to the ContentPanel on the host GroupElement
GridUserControl gridUserControl =
new
GridUserControl();
gridUserControl.Dock = DockStyle.Fill;
gridUserControl.RadGrid.DataSource = assetListingView.AssetBindingSource;
hostGroup.ContentPanel.Controls.Add(gridUserControl);
this
.WorkItem.UIExtensionSites[UIExtensionSiteNames.MainPanelBar].Add<RadPanelBarGroupElement>(hostGroup);
}
Once all of this is set up, the application looks as follows.
Clicking the Add Asset button will invoke the AddNewAsset command and therefor causes a new asset to be added to the grid. Clicking the Remove Asset button will invoke the DeleteSelectedAsset command and therefor causes the currently selected item to be removed from the grid.
The "Navigation Grid" option of the RadPanelBar contains the hosted RadGridView user control. Clicking on an item in either grid causes the other grid's selection to be updated since they are bound to the same datasource.
Click here to download the source code used in this post.