解耦用户界面 [英] decoupling user interface

查看:91
本文介绍了解耦用户界面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好每个人

i想知道我该怎么做:

将用户界面与后端设计模式分离



即。你有移动应用程序来检测具有不同选项的某些类型的设备(电视或空调)(电视 - >开,关,上,下声音...,空调 - >设置煤度,开,关, timer ...),其中移动应用程序加载动态界面,根据检测到的设备功能生成包含选项的表单页面



感谢4所有

解决方案

这不是一个我们可以在这样一个小小的文本框中回答的问题 - 这是一个很大的问题,有很多可能的答案。

最简单的可能是建议您查看各种设计模式: Wiki:Three Tier [ ^ ]可能是一个好的开始。


我想你想要实现一个能够与U交互的数据模型我是组件,对它们一无所知。



.Net为开发此类数据对象提供了坚实的基础。



我通常将这种对象称为实体,首先需要注意的是 INotifyPropertyChanged [ ^ ]界面。



公共类EntityBase:INotifyPropertyChanged 
{
公共事件PropertyChangedEventHandler的PropertyChanged;

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





您需要熟悉的下一个界面是< a href =http://msdn.microsoft.com/en-us/library/system.componentmodel.ieditableobject.aspx> IEditableObject [ ^ ],允许您的对象退出编辑操作。



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

公共类EntityBase:INotifyPropertyChanged,IEditableObject
{
EntityBaseData originalData;
EntityBaseData数据;

公共事件PropertyChangedEventHandler PropertyChanged;

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


//在派生类中重写此方法以创建
//包含该实体数据的对象
protected virtual EntityBaseData CreateData()
{
EntityBaseData result = new EntityBaseData();
返回结果;
}

//在派生类中重写此方法以将更改
//保存到某个存储 - 例如数据库
protected virtual void SaveData()
{
}

protected EntityBaseData GetData()
{
if(data == null)
{
data = CreateData ();
}
返回数据;
}

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;
}
}





您将以这种方式使用上述课程:

公共类PersonData:EntityBaseData 
{
int id;
字符串名称;

public PersonData()
{}

public override EntityBaseData Clone()
{
PersonData result = new PersonData();
result.Id = Id;
result.Name = Name;
返回结果;
}

public int Id
{
get
{
return id;
}
设定
{
id = value;
}
}
公共字符串名称
{
获取
{
返回名称;
}
设置
{
name = value;
}
}
}

公共类PersonEnity:EntityBase
{
私人PersonData数据
{
get
{
return(PersonData)GetData();
}
}

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

public int Id
{
get
{
return Data.Id;
}
设置
{
if(Data.Id == value)
{
return;
}
Data.Id = value;
OnChanged(Id);
}
}
公共字符串名称
{
get
{
return Data.Name;
}
设置
{
if(Data.Name == value)
{
return;
}
Data.Name = value;
OnChanged(姓名);
}
}
}





这适用于单个对象,但它相当通常使用对象列表,这将我们带到通用的 BindingList [ ^ ]课程:



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

公共字符串GetListName(PropertyDescriptor [] listAccessors)
{
string result = typeof(T).Name;
返回结果;
}
}



请注意,我也在实现 ITypedList [ ^ ]界面,提供Visual Studio在设计时使用的类型信息(Windows窗体)



接下来你需要的是组件 [ ^ ]

 public class BindingComponent< T> :Component,IListSource 
{
BindingListEx< T>项目;
public BindingComponent()
{
items = new BindingListEx< T>();
}

public BindingListEx< T>物品
{
获得
{
退货;
}
}


public bool ContainsListCollection
{
get {return false; }
}

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





以上内容现在可用于为PersonEntity创建可绑定数据源

 public class PersonsComponent:BindingComponent< PersonEnity> 
{
public PersonsComponent()
{
}
}



以上内容可与Visual一起使用PersonsComponent应显示在工具箱中的Studio。



嗯,这是在.Net中创建实体类的基础知识。



祝你好运

Espen Harlinn


我建​​议你学习和分析以下架构模式的适用性 http://en.wikipedia.org/wiki/Architectural_pattern_(computer_science) [ ^ ]):



MVVM - 模型视图视图模型,

http://en.wikipedia.org/wiki/Model_View_ViewModel [ ^ ],



MVC - 模型 - 视图 - 控制器,

http://en.wikipedia.org /维基/模型 - 视图控制器 [ ^ ]),



MVA - 模型 - 视图 - 适配器,

http://en.wikipedia.org/wiki/Model-view-adapter [ ^ ],



MVP - 模型 - 视图 - 演示者,

http://en.wikipedia.org/wiki/Model-view-presenter [ ^ ]。

但是看看模式来学习这些想法,不要收集一些食谱食谱。您需要从应用程序的目标开始进行架构工作,并考虑其具体要求。



-SA

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

解决方案

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.


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


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


这篇关于解耦用户界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆