多年来,已经有几种方法可以处理您提到的这些问题,我同意,这是UI框架近年来必须解决的两个主要问题。来自WPF背景,可以通过以下方式进行处理:
声明式设计,而不是命令式
当您刻苦地描述编写代码以实例化控件并设置它们的属性时,您在描述的是UI设计的必要模型。即使使用WinForms设计器,您也只是在该模型上使用包装器-打开Form1.Designer.cs文件,然后看到所有代码。
使用WPF和XAML以及其他框架中的类似模型(当然,从HTML开始),您将需要描述自己的布局,并让该框架承担实现它的繁重工作。您可以使用更智能的控件(例如面板(网格或WrapPanel等))来描述UI元素之间的关系,但是期望您不要手动放置它们。诸如可重复控件(如ASP.NET的Repeater或WPF的ItemsControl)之类的灵活概念可帮助您创建动态缩放的UI,而无需编写重复的代码,从而允许将动态增长的数据实体动态表示为控件。
WPF的DataTemplates允许您再次声明性地定义UI优势的小块,并将它们与您的数据进行匹配;例如,客户数据对象的列表可能绑定到ItemsControl,并根据他是普通员工(使用具有名称和地址的标准网格行模板)还是主要客户来调用不同的数据模板,而不同的模板,带有图片,并显示易于使用的按钮。同样,无需在特定窗口中编写代码,只需更智能的控件即可了解它们的数据上下文,从而使您可以将它们简单地绑定到数据并让它们执行相关的操作。
数据绑定和命令分离
WPF的数据绑定(以及在其他框架中,例如AngularJS)也涉及数据绑定,它允许您通过将控件(例如,文本框)与数据实体(例如,客户的姓名)链接来声明自己的意图。框架处理管道。逻辑处理类似。您可以使用数据绑定机制将控制器的行为(例如,按钮的Command属性)链接到表示活动块的Command对象,而不是将背后的事件处理程序手动连接到基于Controller的业务逻辑。
它允许此命令在Windows之间共享,而无需每次都重写事件处理程序。
更高的抽象水平
与您理所当然感到厌烦的Windows窗体的事件驱动范例相比,这两个针对您两个问题的解决方案都向更高的抽象水平迈进了一步。
这样的想法是,您不想在代码中定义控件具有的每个单个属性,以及从单击按钮开始到之后的每个行为。您希望控件和基础框架为您做更多的工作,并允许您考虑更抽象的数据绑定概念(存在于WinForms中,但远不及WPF有用)和Command模式来定义UI之间的链接和不需要扎根的行为。
该MVVM模式是微软的做法,以这种模式。我建议阅读。
这是该模型的外观以及如何为您节省时间和代码行的粗略示例。这不会编译,但是是伪WPF。:)
在应用程序资源中的某个位置,您可以定义数据模板:
<DataTemplate x:DataType="Customer">
<TextBox Text="{Binding Name}"/>
</DataTemplate>
<DataTemplate x:DataType="PrimeCustomer">
<Image Source="GoldStar.png"/>
<TextBox Text="{Binding Name}"/>
</DataTemplate>
现在,您将主屏幕链接到ViewModel,这是一个公开数据的类。假设有一个客户(简称为List<Customer>
)和一个Command对象(同样是类型的简单公共属性)的集合ICommand
。该链接允许绑定:
public class CustomersnViewModel
{
public List<Customer> Customers {get;}
public ICommand RefreshCustomerListCommand {get;}
}
和用户界面:
<ListBox ItemsSource="{Binding Customers}"/>
<Button Command="{Binding RefreshCustomerListCommand}">Refresh</Button>
就是这样。ListBox的语法将从ViewModel中获取客户列表,并尝试将其呈现到UI。由于我们前面定义了两个DataTemplates,它将导入相关模板(基于DataType,假设PrimeCustomer继承自Customer),并将其作为ListBox的内容。没有循环,没有通过代码动态生成控件。
同样,Button具有将其行为链接到ICommand实现的预先存在的语法,该ICommand实现大概知道会更新Customers
属性-提示数据绑定框架自动再次更新UI。
我当然在这里采取了一些捷径,但这是要点。