Exercise outline

The goal of this exercise is to add a Ribbon button for volume models which helps configuring the input data of volume models in a faster way, automatically generating dialogs that prompt the users to select the input files required for a volume model.

Create a new GUI command

Add a new folder named Commands to the plugin project. Inside this folder, create a new class named AddInputDataToVolumeModelCommand.cs and adapt the contents as shown below.

using System.Drawing;
using System.Windows.Forms;
using DelftTools.Shell.Gui;
using DeltaShell.Plugins.VolumeModel.Importers;
namespace DeltaShell.Plugins.VolumeModel.Commands
{
    internal class AddInputDataToVolumeModelCommand : IGuiCommand
    {
        /// <summary>
        /// The name of the gui command
        /// </summary>
        public string Name
        {
            get { return "Add input data"; }
        }
        /// <summary>
        /// Ensures the gui command is enabled for volume models only
        /// </summary>
        public bool Enabled
        {
            get { return Gui != null && Gui.Selection is Models.VolumeModel; }
        }
        /// <summary>
        /// The image of the gui command
        /// </summary>
        public Image Image { get; set; }
        /// <summary>
        /// Whether or not the gui command is checked
        /// </summary>
        /// <remarks>Not relevant in this tutorial</remarks>
        public bool Checked { get; set; }
        /// <summary>
        /// A reference to the Delta Shell gui (automatically set by Delta Shell logic)
        /// </summary>
        public IGui Gui { get; set; }
        /// <summary>
        /// The action that should be performed while executing the gui command
        /// </summary>
        public void Execute(params object[] arguments)
        {
            // Obtain the selected volume model
            var volumeModel = (Models.VolumeModel)Gui.SelectedModel;
            // Try to obtain a precipitation file via a file dialog
            var fileDialog = new OpenFileDialog
            {
                Title = "Select precipitation time series",
                Filter = "WaterML2 files|*.XML",
                Multiselect = false
            };
            if (fileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            // Create a WaterML2 time series importer
            var waterML2TimeSeriesImporter = new WaterML2TimeSeriesImporter();
            // Import the data from the precipitation file
            waterML2TimeSeriesImporter.ImportItem(fileDialog.FileName, volumeModel.Precipitation);
            // Try to obtain a shape file via a file dialog
            fileDialog = new OpenFileDialog
            {
                Title = "Select basin shape file",
                Filter = "Shape files|*.shp",
                Multiselect = false
            };
            if (fileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            // Create a DrainageBasinImporter importer
            var drainageBasinImporter = new DrainageBasinImporter();
            // Import the data from the shape file
            drainageBasinImporter.ImportItem(fileDialog.FileName, volumeModel.Basin);
        }
        /// <summary>
        /// The action that should be performed in order to undo execute actions of the gui command
        /// </summary>
        /// <remarks>Not relevant in this tutorial</remarks>
        public void Unexecute()
        {
        }
    }
}

The command is derived from the IGuiCommand interface in order to obtain a reference to the Delta Shell gui (which is automatically set by the Delta Shell framework).

The comments in the code explain the different parts of the gui command implementation.

Create a new Ribbon control

Start by downloading documents-stack.png and adding the file to the project resources. This image must be built as a resource in order for WPF to use it, so select the image in the Resources folder shown in the Solution Explorer panel of Visual Studio and change the Build Action property to Resource.

 

Now, add a new folder named Ribbon to the plugin project. Inside this folder, create a new WPF user control named VolumeModelRibbon.xaml and adapt the contents (in the designer) as shown below:

 

<UserControl x:Class="DeltaShell.Plugins.VolumeModel.Ribbon.VolumeModelRibbon"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:fluent="clr-namespace:Fluent;assembly=Fluent"
    mc:Ignorable="d" Height="145" Width="632">
    <!--Create a ribbon control-->
    <fluent:Ribbon Name="VolumeModelRibbonControl" x:FieldModifier="private">
        <!--Create a ribbon tab-->
        <fluent:RibbonTabItem Header="Volume model" fluent:KeyTip.Keys="E">
            <!--Create a ribbon group box-->
            <fluent:RibbonGroupBox Header="Input">
                <!--Create a ribbon button-->
                <fluent:Button x:Name="ButtonAddInputDataToVolumeModel"
                               Header="Add input data"
                               Icon="/DeltaShell.Plugins.VolumeModel;component\Resources\documents-stack.png"
                               ToolTip="Add input data to the selected volume model"
                               Click="ButtonAddInputDataToVolumeModel_OnClick"
                               Size="Middle"
                               SizeDefinition="Middle,Small,Small"/>
            </fluent:RibbonGroupBox>
        </fluent:RibbonTabItem>
    </fluent:Ribbon>
</UserControl>

In order to successfully build the code below, references need to be added to:

  • Fluent

This dll can be found in the packages folder of the solution (D:\VolumeModel\packages\DeltaShell.Framework.1.1.1.34867\lib\net40\DeltaShell).


After adding the references be sure to set the Copy Local property of the references to False to prevent duplication of dll's in the bin folder.

 

Next, adapt the contents of VolumeModelRibbon.xaml.cs as shown below (right click the class | View Code).

 

using System.Collections.Generic;
using System.Windows;
using DelftTools.Controls;
using DelftTools.Shell.Gui;
using DelftTools.Shell.Gui.Forms;
using DeltaShell.Plugins.VolumeModel.Commands;
namespace DeltaShell.Plugins.VolumeModel.Ribbon
{
    /// <summary>
    /// Interaction logic for VolumeModelRibbon.xaml
    /// </summary>
    public partial class VolumeModelRibbon : IRibbonCommandHandler
    {
        private readonly IGuiCommand addInputDataToVolumeModelCommand = new AddInputDataToVolumeModelCommand(); // Instance of the implemented gui command
        /// <summary>
        /// Creates the Ribbon control
        /// </summary>
        public VolumeModelRibbon()
        {
            // Initialize the control (standard user control logic)
            InitializeComponent();
        }
        /// <summary>
        /// Returns the volume model Ribbon control
        /// </summary>
        public object GetRibbonControl()
        {
            return VolumeModelRibbonControl;
        }
        /// <summary>
        /// Enabling/disabling actions to be performed while validating the Ribbon items (triggered by Delta Shell logic)
        /// </summary>
        public void ValidateItems()
        {
            ButtonAddInputDataToVolumeModel.IsEnabled = addInputDataToVolumeModelCommand.Enabled;
        }
        /// <summary>
        /// Whether or not the contextual tab should be visible
        /// </summary>
        public bool IsContextualTabVisible(string tabGroupName, string tabName)
        {
            return false;
        }
        /// <summary>
        /// The (gui) commands of the Ribbon control
        /// </summary>
        public IEnumerable<ICommand> Commands
        {
            get { yield return addInputDataToVolumeModelCommand; }
        }
        /// <summary>
        /// Actions to be performed after clicking the AddInputDataToVolumeModel button
        /// </summary>
        private void ButtonAddInputDataToVolumeModel_OnClick(object sender, RoutedEventArgs e)
        {
            addInputDataToVolumeModelCommand.Execute();
        }
    }
}

The Ribbon control is derived from the IRibbonCommandHandler interface so that it can be registered in the gui plugin.

The comments in the code should explain the different parts of the Ribbon control implementation.

Register the Ribbon control in the gui plugin class

Register the Ribbon control in the GUI plugin by adding the following code to VolumeModelGuiPlugin.cs:

using DelftTools.Shell.Gui.Forms;
using DeltaShell.Plugins.VolumeModel.Ribbon;

and

        public override IRibbonCommandHandler RibbonCommandHandler
        {
            get { return new VolumeModelRibbon(); }
        }

Delta Shell should now automatically add the new Ribbon control to its Ribbon bar during the application startup.

Exercise results

First of all, download the following WaterML2 XML file: WaterML2_precipitation_data.XML. Also download and unzip the shape files contained in the following archive: Gemeenten.zip. You will use all these data along the exercise.

Next, run the application and check that a volume Ribbon button has been added to the Ribbon bar:



Then create a new volume model item (right click on project | Add | New Model ...). Notice that the just created button can only be used when the the volume model is selected in the Project panel. If you select any other item, like the project, or any element inside the volume model, the button will be disabled. Select the added volume model, and then click the volume Ribbon button. In the file selection dialogs that will be automatically prompted, select, sequentially, the previously downloaded precipitation (WaterML2 XML) and basin (shape) files. The model will be fully configured and ready to be run. You can verify that the input data has been correctly added to the volume model by opening the data views or by running the model:

 

  • No labels