Tooltips to the max - expressive UI

XAF Team Blog
08 January 2013

As you know, creating a great UI requires consideration of numerous usability  factors, among them effective use of screen real-estate. Because the visible/active region of an application is limited, much of the information within a data driven application is hidden behind container controls  (tabs, popup forms etc). To access this hidden information requires end-users to navigate to the appropriate UI element.

Using Tooltips to Expose Hidden Information

Tooltips are a powerful UI metaphor and can help you better inform end-users without requiring navigation to different areas of an application. Because our WinForms product line supports tooltips with HTML formatting, you can quickly enable tooltip support within your XAF application as described in this help document.

To fully leverage the flexibility inherent in XAF, I’ll discuss ways in which you can extend the use of tooltips and create highly functional solutions with ease.

Let’s get started by taking a look at our  XVideoRental RWA.

DataOnToolTip

The goal of this implementation is to push any data property of a business object to a tooltip. Our first step is to create an interface and extend our Application Model columns as described in our documentation,

[ModelAbstractClass]

public interface IModelColumnTooltipData : IModelColumn {

    IModelTooltipData TooltipData { get; }

}

public interface IModelTooltipData : IModelNode {

    [Category("DataOnToolTip")]

    bool DataOnToolTip { get; set; }

    [Category("DataOnToolTip")]

    int MaxHeight { get; set; }

    [Category("DataOnToolTip")]

    int MaxWidth { get; set; }

}

 

public class GridViewImageTextToolTipController : ViewController<ListView>, IModelExtender {

    public void ExtendModelInterfaces(ModelInterfaceExtenders extenders) {

        extenders.Add<IModelColumn, IModelColumnTooltipData>();

    }

This code will extend the Application Model as shown below:

image_thumb9

Next, we need to implement a method that will display data within a tooltip when the DataOnTooltip attribute is set:

image_thumb5

It’s important to note that because of the XAF’s MVC like architecture, it is extremely easy to reuse this functionality in any project without writing a single line of code.

ToolTipText

The goal of this example is to provide direction to end-users within the Advanced Banded ListView so they know to double click a row to view more information associated with a specific record. The first step is to extend the Application Model with an attribute:

    public interface IModelTooltipData : IModelNode {

        [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]

        string ToolTipText { get; set; }

//        ...

We can now use the Model Editor to assign the text we want in the ToolTipText attribute and XAF will do the rest for us across any project.

image_thumb8[1]

ToolTipController

Extending the Application Model in order to associate a class (controller) with any of its nodes can be done easily. First we add one more property to our IModelToolTipData interface:

public interface IModelTooltipData : IModelNode {

    [DataSourceProperty("ToolTipControllers")]

    [TypeConverter(typeof(StringToTypeConverterBase))]

    Type ToolTipController { get; set; }

 

    [Browsable(false)]

    IEnumerable<Type> ToolTipControllers { get; }

The TypeConverter attribute will convert the type to a string so it will be possible for the Model Editor to show it and the DataSourceProperty attribute will populate the Types (Controllers) we require. What's remains is to decide which classes will be in that list. This can be done by writing Domain Logic for the non browsable ToolTipControllers enumeration:

[DomainLogic(typeof(IModelTooltipData))]

public class IModelToolTipControllerDomainLogic  {

    public static IEnumerable<Type> Get_ToolTipControllers(IModelToolTipController modelToolTipController) {

        return FindTypeDescenants(typeof(ObjectToolTipController));

    }

    protected static IEnumerable<Type> FindTypeDescenants(Type type) {

        var typeInfo = XafTypesInfo.Instance.FindTypeInfo(type);

        return ReflectionHelper.FindTypeDescendants(typeInfo).Where(info => !info.IsAbstract).Select(info => info.Type);

    }

 

}

 

Now that we’ve finished the Application Model extension, let’s see how straightforward it is to write and apply such a controller for our Movie business object. For a very simple ToolTipController like:

public class MovieToolTipController : ObjectToolTipController {

    const int MaxPhotoWidth = 120, MaxPhotoHeight = 120;

    public MovieToolTipController(Control parent) : base(parent) { }

 

    protected override void InitToolTipItem(ToolTipItem item) {

        var movie = ObjectSpace.FindObject<Movie>(CriteriaOperator.Parse("MovieTitle=?", EditObject));

        var photo = movie.Photo;

        if (photo != null)

            item.Image = photo.CreateImage(MaxPhotoWidth, MaxPhotoHeight);

        item.Text = GetMovieInfoHtml(movie);

    }

    public string GetMovieInfoHtml(Movie movie) {

        return string.Format("<b>{0}</b>\r\n<i>{2:D}</i>\r\r\n{1}", movie.Title, movie.Plot, movie.ReleaseDate);

    }

 

}

When we assign it to a listview column:

image_thumb8

XAF will automatically display an HTML formatted tooltip:

image_thumb5[1]

We can use a similar approach for PivotGridListEditors:

image_thumb12

Everything discussed in this post is included in the Common.Win project under the Common.Win.General.ToolTip namespace of our XVideoRental demo.

Let us know if you have questions or subjects you’d like us to cover.

Until next time, Happy XAFing to everybody!

Free DevExpress Products - Get Your Copy Today

The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the DevExpress Support Center at your convenience. We'll be happy to follow-up.
No Comments

Please login or register to post comments.