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!\\
\\
\\
|