Skip to main content

Implement a View Item

  • 5 minutes to read

This topic demonstrates how to implement a custom View Item and display it on all Detail Views. This View Item shows an image that corresponds to a specific business object type. You can specify this image in the Application Model. To display this View Item, we use a WinForms-specific control for demonstration purposes.

IconDetailItem

Tip

A complete sample project is available in the DevExpress Code Examples database at https://supportcenter.devexpress.com/ticket/details/e242/how-to-implement-a-detail-view-item.

A custom View Item’s implementation process consists of two parts:

Create a View Item

  1. Create a ViewItem class descendant and name it “ClassIconDetailItem” in the WinForms module project (MySolution.Module.Win). If your solution does not contain this project, add this View Item to the WinForms application project (MySolution.Win).
  2. Override the CreateControlCore method to create a control that represents the View Item in a UI.
  3. Create a custom interface that implements the IModelViewItem and name it “IModelClassIcon”.
  4. In this interface, define properties that coincide with View Item’s properties you want to use in the Application Model. Do not define any properties in this interface if you do not want to specify a View Item’s properties in the Application Model.
  5. Pass this interface to the View Item’s constructor as the the model parameter. This allows to initialize and configure the View Item using the data from the corresponding Application Model’s node.
  6. Decorate the ClassIconDetailItem class with the ViewItemAttribute and pass the IModelClassIcon interface as an attribute’s parameter. This displays a new child node in the Application Model’s ViewItems node after the solution rebuilds. RegisteredClassIcon

The following code demonstrates the custom View Item:

using System;
using System.Drawing;
using System.Windows.Forms;
using DevExpress.ExpressApp.Editors;
using DevExpress.ExpressApp.Model;
using DevExpress.ExpressApp.Utils;
//...
public interface IModelClassIcon : IModelViewItem { }

[ViewItemAttribute(typeof(IModelClassIcon))]
public class ClassIconDetailItem : ViewItem {
    private IModelClassIcon Info;
    public ClassIconDetailItem(IModelClassIcon info, Type classType)
        : base(classType, info.Id) {
        Info = info;
    }
    protected override object CreateControlCore() {
        PictureBox imageControl = new PictureBox();
        string imageName = ((IModelDetailView)Info.Parent.Parent).ImageName;
        ImageInfo imageInfo = ImageLoader.Instance.GetLargeImageInfo(imageName);
        if(imageInfo.IsEmpty) {
            imageControl.Visible = false;
        }
        else {
            Image image = imageInfo.Image;
            imageControl.Image = image;
            imageControl.Width = image.Width;
            imageControl.Height = image.Height;
        }
        return imageControl;
    }
}

Add the Custom View Item on a Detail View

  1. Implement the ModelNodesGeneratorUpdater<T> descendants (Generator Updaters) for the ModelDetailViewLayoutNodesGenerator and ModelDetailViewItemsNodesGenerator Node Generators in the WinForms module project (MySolution.Module.Win). If your solution does not contain this project, add these updaters to the WinForms application project (MySolution.Win). Name them “MyDetailViewLayoutUpdater” and “MyDetailViewItemUpdater”.
  2. Register these Updaters in the WinForms module class descendant’s overridden ModuleBase.AddGeneratorUpdaters method.

The following code shows how to do this:

using System.ComponentModel;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Model;
using DevExpress.ExpressApp.Model.NodeGenerators;
using DevExpress.ExpressApp.Model.Core;
using DevExpress.ExpressApp.Layout;
//...
public class MyDetailViewLayoutUpdater : ModelNodesGeneratorUpdater<ModelDetailViewLayoutNodesGenerator> {
    public override void UpdateNode(ModelNode node) {
        IModelViewLayout layoutNode = (IModelViewLayout)node;
        IModelLayoutGroup mainGroup = 
            layoutNode.GetNode(ModelDetailViewLayoutNodesGenerator.MainLayoutGroupName) as IModelLayoutGroup;
        mainGroup.Direction = FlowDirection.Horizontal;
        IModelLayoutViewItem myItem = mainGroup.AddNode<IModelLayoutViewItem>("Icon");
        myItem.Index = int.MinValue;
        myItem.MaxSize = new System.Drawing.Size(64, 64);
        myItem.SizeConstraintsType = XafSizeConstraintsType.Custom;
        myItem.ViewItem = ((IModelCompositeView)layoutNode.Parent).Items.GetNode("Icon") as IModelViewItem;
    }
}

public class MyDetailViewItemUpdater : ModelNodesGeneratorUpdater<ModelDetailViewItemsNodesGenerator> {
    public override void UpdateNode(ModelNode node) {
        IModelViewItems itemsNode = (IModelViewItems)node;
        itemsNode.AddNode<IModelClassIcon>("Icon");
    }
}

[ToolboxItemFilter("Xaf.Platform.Win")]
public sealed partial class MySolutionWindowsFormsModule : ModuleBase {
    // ...
    public override void AddGeneratorUpdaters(ModelNodesGeneratorUpdaters updaters) {
        base.AddGeneratorUpdaters(updaters);
        updaters.Add(new MyDetailViewLayoutUpdater());
        updaters.Add(new MyDetailViewItemUpdater());
    }
}

Run the application and ensure that all the Detail Views contain class icons.

See Also