Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
scrollbar

h2. Exercise outline

{color:#000000}The goal of this exercise is to build a custom view for volume models. As an example, after this exercise it should be possible to show the input data of volume models{color} {color:#000000}partially on a map (the catchments) and{color} {color:#000000}partially in a table/chart (the{color} precipitation {color:#000000}data), all in one single view.{color}


h2. Create a new view

Add to the plugin project a new folder named _Views_. In this folder, create a new *user control* named _VolumeModelView.cs_ and adapt the contents as shown below (right click the class in the Solution Explorer \| View Code).

{note}
A reference to _DeltaShell.Plugins.CommonTools.Gui_ needs to be  added in order to successfully build the code below (right click the  References folder of the project in the Solution Explorer \| Add  Reference... \| Browse... \| Select _D:\VolumeModel\packages\DeltaShell.1.0.0\delta-shell\plugins\DeltaShell.Plugins.CommonTools.Gui\DeltaShell.Plugins.CommonTools.Gui.dll_).
{note}



{code}
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
using DelftTools.Controls;
using DeltaShell.Plugins.CommonTools.Gui.Forms.Functions;
using SharpMap.Data.Providers;
using SharpMap.Layers;
using SharpMap.UI.Forms;

namespace DeltaShell.Plugins.VolumeModel.Views
{
    public partial class VolumeModelView : UserControl, IView
    {
        private Models.VolumeModel volumeModel;
        private readonly MapControl mapControl;
        private readonly FunctionView functionView;

        /// <summary>
        /// Creates a volume model view
        /// </summary>
        public VolumeModelView()
        {
            // Initialize the view (standard user control logic)
            InitializeComponent();

            // Create a map control
            mapControl = new MapControl { Dock = DockStyle.Fill };

            // Create a function view
            functionView = new FunctionView { Dock = DockStyle.Fill };

            // Create a split container which contains the map control and the function view
            var splitContainer = new SplitContainer
                {
                    Dock = DockStyle.Fill,
                    Orientation = Orientation.Horizontal,
                    Panel1 = { Controls = { mapControl } },
                    Panel2 = { Controls = { functionView } }
                };

            // Add the split container to the user control
            Controls.Add(splitContainer);
        }

        /// <summary>
        /// The volume data of the view
        /// </summary>
        public object Data
        {
            get { return volumeModel; }
            set
            {
                volumeModel = value as Models.VolumeModel;

                if (volumeModel == null)
                {
                    return; // Do nothing if the data is null or not a volume model
                }

                // Create a layer for the catchments in the basin
                var vectorLayer = new VectorLayer
                    {
                        LabelLayer = { Visible = true, LabelColumn = "Name" },
                        DataSource = new FeatureCollection
                        {
                            Features = (IList)volumeModel.Basin.Catchments
                        }
                    };

                // Ensure the map control is zoomed to extents after adding or removing features
                vectorLayer.DataSource.FeaturesChanged += (s, o) => mapControl.Map.ZoomToExtents();

                // Add the new layer to the map control
                mapControl.Map.Layers.Add(vectorLayer);

                // Add the precipitation time series to the function view
                functionView.Data = volumeModel.Precipitation;
            }
        }

        /// <summary>
        /// The image of the volume model view
        /// </summary>
        public Image Image { get; set; }

        /// <summary>
        /// The meta information of the volume model view (which is automatically set by Delta Shell logic)
        /// </summary>
        public ViewInfo ViewInfo { get; set; }

        /// <summary>
        /// Makes the provided <paramref name="item"/> visible (if implemented so)
        /// </summary>
        /// <remarks>Not part of this tutorial</remarks>
        public void EnsureVisible(object item)
        {

        }
    }
}

{code}


{info}


The custom view class is derived from the _IView_ interface so that it can be registered in the gui plugin (see the next step).

The comments in the code explain the different parts of the view implementation.
{info}

{note}
A description on the backgrounds and usage of _MapControl_ and _FunctionView_ is not part of this tutorial.
{note}

h2. Register the view in the gui plugin class

Register the custom view in the gui plugin by adding the following code to _VolumeModelGuiPlugin.cs_:

{code}
using DelftTools.Controls;
using DeltaShell.Plugins.VolumeModel.Views;
{code}

and

{code}
        public override IEnumerable<ViewInfo> GetViewInfoObjects()
        {
            yield return new ViewInfo<Models.VolumeModel, VolumeModelView> { Name = "Volume model view" };
        }
{code}

Delta Shell should now be able to open a custom view for volume models, containing a map, a table and a chart control.


h2. Exercise results

Set up a volume model as described in the results of the previous exercise ([TOOLS:Create a simple hydrological model]).

This time, during the creation of the model, a dialog containing two types of views will pop up:

!Volume model view selection dialog.png!\\
\\
Select _Volume model view_ and the newly implemented view will become visible:

!Empty model view.png|border=1!\\
\\
After importing some catchment and precipitation data, the view controls should be automatically updated:

!ModelView.png|border=1!\\
\\
\\
Panel
borderStylenone
Align
centercenter

The code results up until the end of this exercise can be downloaded here