Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create Ribbon tabs dynamically?

I want to start development of new application using PrismV4, MEF, Ribbon. But now, I have a problem. How to create tabs for Ribbon dynamically? Each module in application could create own tab in Ribbon. And each tab may have many groups.

How can it be done? Where do I need to place each group's definitions (what controls to use (buttons, textboxes, comboboxes, etc) and command bindings and how?

Do I need to write XAML somewhere in Module, or all it can be done by code? And last question, how to notify Ribbon (in Shell) to add these tabs to Ribbon? Shall I use EventAggregator to communicate from Module to Shell? Or?

like image 709
Lari13 Avatar asked Dec 29 '10 11:12

Lari13


1 Answers

For non-contextual tabs, my favorite approach for this problem is to dynamically load components (via reflection for instance) that include XAMLs with binding to commands and VMs (or controllers) that include the command implementations and perform that command bindings.

For contextual tabs, my favorite approach is to include a dictionary of Model to ViewModel mappings, then activate/deactivate contextual tabs by name, that were loaded using the above approach (and pass the correct data context to them - the view model).

Pseudo code should be more or less like this (depending on what your frameworks implement and what you have to implement yourself):

// Deserialize UI controllers from configuration files
// Each controller should act as view-model for its UI elements

// Register controllers with UI Manager
foreach controller in config.UiControllers uiManager.AddController(controller);


void UiManager.AddController(UiController controller)
{
    // Load controller's tool windows
    foreach toolWindow in contoller.toolWindows
    {
         toolWindow.LoadResources();
         toolWindow.DataContext = controller;
         mainWindow.AddToolWindow(toolWindow, contoller.PreferedUiRegion);
    }

    // Load controller's toolbars
    foreach toolBar in controller.ToolBars
    {
         toolBar.DataContext = controller;
         mainWindow.AddToolBar(toolBar);
    }

    // Load controller's contextual toolbar groups
    foreach group in controller.ContextualToolBarGroups
    {
         group.DataContext = controller;
         mainWindow.AddContextualToolBarGroupr(group);
    }

    // Load view models for specific model types
    foreach item in controller.ViewModelsDictionary
    {
         this.RegisterViewModelType(item.ModelType, item.ViewModelType, item.ViewType);
    }
}


void UiManager.OnItemSelected(Object selectedItem)
{
    var viewModelType = GetViewModelTypeFromDictionary(selectedItem);
    var viewType = GetViewTypeFromDictionary(selectedItem) ?? typeof(ContentPresentor);

    var viewModel = Reflect.CreateObject(viewModelType);
    var view = Reflection.CreateObject(viewType);

    viewModel.Model = selectItem;
    view.DataContext = viewModel;

    // Enable activation of contextual tab group on activate of view (if user clicks on it)
    view.OnActivatedCommandParameter = viewModel.ContextualTabGroupName;

    // This command should ask mainWindow to find contextual tab group, by name, and activate it
    view.OnActivatedCommand = ModelActivatedCommand;

    mainWindow.DocumentArea.Content = view;
}
like image 98
Danny Varod Avatar answered Sep 30 '22 11:09

Danny Varod