Click here to Skip to main content
15,886,518 members
Please Sign up or sign in to vote.
3.33/5 (3 votes)
See more:
hello every body
i want to know how can i do :
decoupling user interface from back end design patterns

ie. you have mobile application to detect certain type of devices (tv or air condition ) which have different options (tv -> on, off ,up and down sound ... ,Air condition -> set coal degree ,on ,off ,timer...) ,where the mobile application load dynamic interface which produce the form page containing options according to detected device functionality

thanks 4 all
Posted
Updated 28-Jan-13 20:44pm
v3
Comments
Ibrahim Uylas 28-Jan-13 10:26am    
What is your purpose? Please give more detail
Jameel VM 28-Jan-13 10:30am    
Please improve your question.

I guess you want to implement a datamodel that is able to interact with the UI components, without knowing anything about them.

.Net provides a solid foundation for developing this kind of data objects.

I usually call this kind of objects for entities, and the first thing you need to look at is the INotifyPropertyChanged[^] interface.

public class EntityBase : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;
  
  protected void OnChanged(string propertyName)
  {
    if(PropertyChanged != null)
    {
      var eventArgs = new PropertyChangedEventArgs(propertyName) 
      PropertyChanged(this, eventArgs);
    }
  }
}


The next interface you need to be familiar with is the IEditableObject[^] which allows your object to back out of an editing operation.

public class EntityBaseData
{
  public virtual EntityBaseData Clone()
  {
    return new EntityBaseData();  
  }
}

public class EntityBase : INotifyPropertyChanged, IEditableObject
{
  EntityBaseData originalData;
  EntityBaseData data;

  public event PropertyChangedEventHandler PropertyChanged;
  
  protected void OnChanged(string propertyName)
  {
    if(PropertyChanged != null)
    {
      var eventArgs = new PropertyChangedEventArgs(propertyName) 
      PropertyChanged(this, eventArgs);
    }
  }
 

  // override this method in a derived class to create
  // an object that contains the data for that entity
  protected virtual EntityBaseData CreateData()
  {
    EntityBaseData result = new EntityBaseData();
    return result;
  }

  // override this method in a derived class to save changes
  // to some storage - such as a database
  protected virtual void SaveData()
  {
  }  

  protected EntityBaseData GetData()
  {
    if(data == null)   
    {
      data = CreateData();
    }
    return data;
  } 

  void IEditableObject.BeginEdit()
  {
    if(originalData == null)
    {
      originalData = GetData();
      data = originalData.Clone();
    }
  }
  
  void IEditableObject.CancelEdit()
  {
    if(originalData != null)
    {
      data = originalData;
      originalData = null;
      OnChanged("");
    }
  }

  void IEditableObject.EndEdit() 
  {
    SaveData();
    originalData = null;
  }
}


You would use the above classes in this manner:
public class PersonData : EntityBaseData
{
 int id;
 string name;

 public PersonData()
 { } 
  
 public override EntityBaseData Clone() 
 {
   PersonData result = new PersonData(); 
   result.Id = Id;
   result.Name = Name;
   return result;
 }

  public int Id
  {
    get
    {
      return id;
    }
    set
    {
      id = value;
    }
  }
  public string Name
  {
    get
    {
      return name;
    }
    set
    {
      name = value;
    }
  } 
}

public class PersonEnity : EntityBase
{
  private PersonData Data
  {
    get
    {
      return (PersonData)GetData();
    }
  }

  protected override EntityBaseData CreateData()
  {
    return new PersonData();
  }

  public int Id
  {
    get
    {
      return Data.Id;
    }
    set
    {
      if (Data.Id == value)
      {
        return;
      }
      Data.Id = value;
      OnChanged("Id");
    }
  }
  public string Name
  {
    get
    {
      return Data.Name;
    }
    set
    {
      if (Data.Name == value)
      {
        return;
      }
      Data.Name = value;
      OnChanged("Name");
    }
  } 
}


This works well for a single object, but it is quite common to work with lists of objects, which brings us to the generic BindingList[^] class:

public class BindingListEx<T> : BindingList<T>, ITypedList
{
  [NonSerialized()]
  private PropertyDescriptorCollection propertyDescriptorCollection;
  public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
  {
    if (listAccessors != null && listAccessors.Length > 0)
    {
      PropertyDescriptorCollection result = ListBindingHelper.GetListItemProperties(listAccessors[0].PropertyType);
      return result;
    }
    else
    {
      if (propertyDescriptorCollection == null)
      {
        propertyDescriptorCollection = TypeDescriptor.GetProperties(typeof(T), new Attribute[] { new BrowsableAttribute(true) });
      }
      return propertyDescriptorCollection;
    }
  }

  public string GetListName(PropertyDescriptor[] listAccessors)
  {
    string result = typeof(T).Name;
    return result;
  }
}

Note that I'm also implementing the ITypedList[^] interface, which provides type information used by Visual Studio during designtime (Windows Forms)

The next thing you need is a Component[^]
public class BindingComponent<T> : Component,IListSource
{
  BindingListEx<T> items;
  public BindingComponent()
  {
    items = new BindingListEx<T>();
  }

  public BindingListEx<T> Items
  {
    get
    {
      return items;
    }
  }


  public bool ContainsListCollection
  {
    get { return false; }
  }

  public System.Collections.IList GetList()
  {
    return Items;    
  }
}


The above can now be used to create a bindable data source for PersonEntity
public class PersonsComponent : BindingComponent<PersonEnity>
{
 public PersonsComponent()
 { 
 }
}

The above can be used with Visual Studio where PersonsComponent should show up in the toolbox.

Well, this is the basics for creating entity classes in .Net.

Best regards
Espen Harlinn
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 28-Jan-13 15:58pm    
Good ideas, effort, a 5.
—SA
Espen Harlinn 28-Jan-13 15:59pm    
Thank you, Sergey
Jibesh 28-Jan-13 19:59pm    
my 5 Espen. you almost make OPs life easier ;)
Espen Harlinn 29-Jan-13 3:25am    
Thank you, jibesh :-D
I suggest you learn and analyze applicability of the following architectural patterns (http://en.wikipedia.org/wiki/Architectural_pattern_(computer_science)[^]):

MVVM — Model View View Model,
http://en.wikipedia.org/wiki/Model_View_ViewModel[^],

MVC — Model-View-Controller,
http://en.wikipedia.org/wiki/Model-view-controller[^]),

MVA — Model-View-Adapter,
http://en.wikipedia.org/wiki/Model–view–adapter[^],

MVP — Model-View-Presenter,
http://en.wikipedia.org/wiki/Model-view-presenter[^].
But look at the pattens to learn the ideas, not to collect some cookbook recipes. You need to do architectural work starting from the goals of your application, taking into account its specific requirements.

—SA
 
Share this answer
 
Comments
Espen Harlinn 28-Jan-13 14:36pm    
Good links :-D
Sergey Alexandrovich Kryukov 28-Jan-13 15:57pm    
Thank you, Espen.
—SA
That isn't really a question we can answer in a little tiny text box like this - it's a big question, with a lot of possible answers.
The simplest is probably to suggest that you look at various design patterns: Wiki: Three Tier[^] would probably be a good start.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 28-Jan-13 11:29am    
Right, a 5. A also suggested to see architectural material — main well-known patterns — please see.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900