Best Design Pattern for Coupling User Interface Components and Data Structures

Posted by szahn on Programmers See other posts from Programmers or by szahn
Published on 2012-12-13T18:55:20Z Indexed on 2012/12/13 23:19 UTC
Read the original article Hit count: 440

I have a windows desktop application with a tree view. Due to lack of a sound data-binding solution for a tree view, I've implemented my own layer of abstraction on it to bind nodes to my own data structure.

The requirements are as follows:

  1. Populate a tree view with nodes that resemble fields in a data structure.
  2. When a node is clicked, display the appropriate control to modify the value of that property in the instance of the data structure.

The tree view is populated with instances of custom TreeNode classes that inherit from TreeNode. The responsibility of each custom TreeNode class is to (1) format the node text to represent the name and value of the associated field in my data structure, (2) return the control used to modify the property value, (3) get the value of the field in the control (3) set the field's value from the control.

My custom TreeNode implementation has a property called "Control" which retrieves the proper custom control in the form of the base control.

The control instance is stored in the custom node and instantiated upon first retrieval. So each, custom node has an associated custom control which extends a base abstract control class.

Example TreeNode implementation:

    //The Tree Node Base Class
    public abstract class TreeViewNodeBase : TreeNode {

    public abstract CustomControlBase Control { get; }

    public TreeViewNodeBase(ExtractionField field)
    {
        UpdateControl(field);
    }

    public virtual void UpdateControl(ExtractionField field)
    {
        Control.UpdateControl(field);
        UpdateCaption(FormatValueForCaption());
    }

    public virtual void SaveChanges(ExtractionField field)
    {
        Control.SaveChanges(field);
        UpdateCaption(FormatValueForCaption());
    }

    public virtual string FormatValueForCaption()
    {
        return Control.FormatValueForCaption();
    }

    public virtual void UpdateCaption(string newValue)
    {
        this.Text = Caption;
        this.LongText = newValue;
    }

}

    //The tree node implementation class
    public class ExtractionTypeNode : TreeViewNodeBase
{
    private CustomDropDownControl control;
    public override CustomControlBase Control
    {
        get
        {
            if (control == null)
            {
                control = new CustomDropDownControl();
                control.label1.Text = Caption;
                control.comboBox1.Items.Clear();
                control.comboBox1.Items.AddRange(
                                        Enum.GetNames(
                                        typeof(ExtractionField.ExtractionType)));
            }
            return control;
        }
    }

    public ExtractionTypeNode(ExtractionField field)
        : base(field) {

    }

}


    //The custom control base class
    public abstract class CustomControlBase : UserControl {
    public abstract void UpdateControl(ExtractionField field);
    public abstract void SaveChanges(ExtractionField field);
    public abstract string FormatValueForCaption();
}

    //The custom control generic implementation (view)
    public partial class CustomDropDownControl : CustomControlBase {
    public CustomDropDownControl()
    {
        InitializeComponent();
    }

    public override void UpdateControl(ExtractionField field)
    {
                    //Nothing to do here
    }
    public override void SaveChanges(ExtractionField field)
    {
                    //Nothing to do here
    }
    public override string FormatValueForCaption()
    {
                    //Nothing to do here
        return string.Empty;
    }
}

    //The custom control specific implementation
    public class FieldExtractionTypeControl : CustomDropDownControl {
    public override void UpdateControl(ExtractionField field)
    {
        comboBox1.SelectedIndex = 
                    comboBox1.FindStringExact(field.Extraction.ToString());
    }

    public override void SaveChanges(ExtractionField field)
    {
        field.Extraction = (ExtractionField.ExtractionType)
                    Enum.Parse(typeof(ExtractionField.ExtractionType),
            comboBox1.SelectedItem.ToString());
    }

    public override string FormatValueForCaption()
    {
        return string.Empty;
    }

The problem is that I have "generic" controls which inherit from CustomControlBase. These are just "views" with no logic. Then I have specific controls that inherit from the generic controls. I don't have any functions or business logic in the generic controls because the specific controls should govern how data is associated with the data structure.

What is the best design pattern for this?

© Programmers or respective owner

Related posts about design

Related posts about design-patterns