Free cookie consent management tool by TermsFeed Policy Generator

Changes between Version 1 and Version 2 of Documentation/DevelopmentCenter/CreateNewViews


Ignore:
Timestamp:
04/05/12 19:17:35 (13 years ago)
Author:
mkommend
Comment:

improved howto views

Legend:

Unmodified
Added
Removed
Modified
  • Documentation/DevelopmentCenter/CreateNewViews

    v1 v2  
    1 = Views in HL3 =
     1= How to ... implement a view =
    22
    3 == Attributes ==
    4  * View
    5  * Content
     3In HeuristicLab contents and views are strictly separated. A view must be derived from `IContentView` and tagged with a `ViewAttribute` and `ContentAttribute`. The reason behind this is, that the `MainFormManager` automatically discovers all classes of type `IContentView` to allow the automatic display of contents by the `MainForm`.
    64
    7 == Methods to override: ==
    8 
    9 {{{#!java
    10 public new Algorithm Content {
    11 get { return (T)base.Content; }
    12 set { base.Content = value; }
    13 }
    14 
    15 protected override void OnContentChanged() {
    16   base.OnContentChanged();
    17   if (Content != null) {
    18     // set controls to Content values
    19   } else {
    20     // set default values in controls
    21   }
    22 }
    23 
    24 protected override void RegisterContentEvents() {
    25  
    26 }
    27 
    28 protected override void DeRegisterContentEvents() {
    29  
    30 }
     5{{{#!csharp
     6MainFormManager.MainForm.ShowContent(IContent content);                     //displays the content with its default view
     7MainFormManager.MainForm.ShowContent(IContent content, Type viewType);      //displays the content with the specified view type
    318}}}
    329
    33 Events happen asynchronous --> Invoke required.
     10In addition, there is an specialized control provided that is able to display arbitrary contents, the `ViewHost`. It can be used if the content type is not known during compile time, for example in collection views. In the following the implementation of the `StringConvertibleValueView` will be explaind in detail to describe the core functionality of the view concept in HeuristicLab.
    3411
    35 Views must still work if content is NULL.
    36 {{{#!java
    37 private void Content_XYZChanged(object sender, System.EventArgs e) {
    38   if (InvokeRequired) {
    39     Invoke(new EventHandler(Content_ExecutionStateChanged), sender, e);
    40   } else {
    41     // set controls
    42     SetEnabledStateControls();
     12
     13The `StringConvertibleValueView` is located in HeuristicLab.Data.View and consists of a label and a textbox.
     14
     15TODO insert image of !StringConvertibleValueView
     16
     17== Frame of HeuristicLab views ==
     18
     19{{{#!csharp
     20  [View("StringConvertibleValue View")]
     21  [Content(typeof(IStringConvertibleValue), true)]
     22  public partial class StringConvertibleValueView : AsynchronousContentView {
     23    public new IStringConvertibleValue Content {
     24      get { return (IStringConvertibleValue)base.Content; }
     25      set { base.Content = value; }
     26    }
    4327  }
    44 }
    4528}}}
    4629
    47 === SetEnabledStateOfControls: ===
     30First of all, one will notice the two attributes on the `StringConvertibleValueView`. The `ViewAttribute` is responsible for providing an identifier that can be used in the GUI. The second attribute, the `ContentAttribute`, is more important as it states which type of contents can be displayed by the view. The first parameter of the `ContentAttribute` states the displayable content types and the second parameter wheter or not the view should be used per default for this content type. In this example, the `StringConvertibleValueView` can display all contents of type `IStringConvertibleValue` and furthermore is used as a default. It is important that it can only exists one default view per content type, because otherwise it is undecidable which view should be used to display the according content.
    4831
    49 In principle all Views have 2 possible states:
    50 * Locked:
    51 * ReadOnly: cf. Results --> those can't be changed; this is not configured in the object graph but in the views
     32== Registering content events and updating of controls ==
    5233
    53 * Either via ViewHost or manually
     34{{{#!csharp
     35    protected override void DeregisterContentEvents() {
     36      Content.ValueChanged -= new EventHandler(Content_ValueChanged);
     37      base.DeregisterContentEvents();
     38    }
    5439
    55 OnContentChanged --> update content here
    56 SetEnabledStateOfControls --> only update enabled and readonly here
     40    protected override void OnContentChanged() {
     41      base.OnContentChanged();
     42      if (Content == null) {
     43        valueTextBox.Text = string.Empty;
     44      } else
     45        valueTextBox.Text = Content.GetValue();
     46    }
    5747
    58 === Default Views: ===
    59  * The most specific default view is used for inherited classes.
     48    protected override void RegisterContentEvents() {
     49      base.RegisterContentEvents();
     50      Content.ValueChanged += new EventHandler(Content_ValueChanged);
     51    }
     52
     53   private void Content_ValueChanged(object sender, EventArgs e) {
     54      if (InvokeRequired)
     55        Invoke(new EventHandler(Content_ValueChanged), sender, e);
     56      else
     57        valueTextBox.Text = Content.GetValue();
     58    }
     59}}}
     60
     61If a new content is set in a view, first the `DeregisterContentEvents` method is called, afterwards `OnContentChanged` and at last `RegisterContentEvents`. `DeregisterContentEvents` is responsible for deregistering events from the "old" content, and is only called if the old content is not null. `OnContentChanged` the controls in the view must be filled with the properties of the content, in this case the valueTextBox is either populated with the result of `Content.GetValue()` or displays nothing (`String.Empty`) if the content is null. `RegisterContentEvents` is the equivalent to `DeregisterContentEvents` for registering necessary events on the new content object. If the `Content` changes its value the previously registered `Content_ValueChanged` method is called and the value of the `TextBox` is updated. Please keep in mind, that these events are often called asynchronous and therefore, an `InvokeRequired` check with according `Invoke` call is necessary (more information on [http://msdn.microsoft.com/en-us/library/ms171728.aspx thread-safe calls to controls]).
     62
     63== Enabling & Disabling of Controls ==
     64Every HeuristicLab view has the two states `Locked` and `ReadOnly` that are used to indicate if an operation is in progress and contents should not be altered, e.g. saving to a file or a running algorithm. Changes to these two properties, as well as content changes, trigger to following overriden method.
     65
     66{{{#!csharp
     67 protected override void SetEnabledStateOfControls() {
     68      base.SetEnabledStateOfControls();
     69      valueTextBox.Enabled = !Locked && Content != null;
     70      valueTextBox.ReadOnly = ReadOnly;
     71    }
     72}}}
     73
     74In `SetEnabledStateOfControls` used controls must be adapted according to the current state of the view. If other HeuristicLab views are nested in the current view, no additional handling is necessary, as state changes are automatically propagated by the base class.
     75
     76The Locked state of a view is set if a operation is in progress and !ReadOnly is used if the content object itself indicates that it must not be changed. Most times the enabled property corresponds to the Locked state and additionally to !ReadOnly if not separates handling is provided by the control.
    6077
    6178
    62 protected override void SetEnabledStateOfControls() {
     79This covers the main parts that must be kept in mind when developing new views for HeuristicLab. You can find the source code of the `StringConvertibleValueView` used as an example attached to this page.
    6380
    64 }
    65 
    66 === NamedItems: ===
    67 You should make sure that if CanChangeName is false --> ReadOnly
    68 
    69 private void Content_NameChanged(object sender, EventArgs e) {
    70   if (InvokeRequired) {
    71     Invoke(...);
    72   } else {
    73    
    74   }
    75 }
    76 
    77 AsynchronosContentView, ItemView --> derive from those, not from ContentView or other views in MainForm.WindowsForm (uses Invoke synchronous --> can get messy).
    78 
    79 Andreas has prepared a useful snippet that you may use to easily create a template for your view.
    80 
    81 
    82 == General advice: ==
    83 If you program views that are not sealed --> make everything protected to allow inheritance.