此文章由机器翻译。
Xamarin
执行并在 Xamarin 中使用数据绑定
数据绑定是一个流行的概念,在编程这几天,尤其是对客户端应用程序中。在这篇文章中,我将讨论哪些数据绑定是和它如何使用本机,如 Windows XAML 支持它的技术。我盖可观察的属性,数据绑定和如何这些可用于不支持数据绑定"开箱即用"的技术的基本原理后,看看如何可以将数据绑定支持添加到 Xamarin.Android 和 Xamarin.iOS 使用 MVVM 光工具包 (mvvmlight.net)。这个轻量级的工具包是最受欢迎的模型-视图-模型 (MVVM) 框架,为 Windows 演示文稿基础 (WPF)、 Silverlight、 Windows Phone、 Windows 应用商店、 Xamarin.Android、 Xamarin.iOS、 Xamarin.Forms 和更多的平台。
我会总结讨论的是 Xamarin.Forms,新加入的 Xamarin 框架,它允许您一次,生成在 XAML 中的 UI 并运行 Android、 iOS 和 Windows Phone 中的数据绑定。
什么数据绑定?
数据绑定是连接 UI 和业务逻辑的过程。通过数据绑定两个连接的属性将保持同步。这是伟大的因为当您更改对象 (数据模型,通常被称为 ViewModel) 上的值,在 UI 中相应的属性也将会自动更新。同样,如果要"双向"数据绑定,在 UI 中的值的修改将自动能更新 ViewModel,以及。数据绑定已经可供客户端应用程序一段时间,即使之前介绍了 WPF 和所有其他基于 XAML 的技术。例如,ASP.NET Web 窗体的数据控件 (如列表框中可以将数据绑定到需要在屏幕上代表的项的集合。为了"转化"的数据项目的可视化表示形式,通常定义项目模板。这是一个小片段的 HTML 代码中的某些控件显示数据项目的属性中包含的值。
在 XAML 中,这一概念已扩展和它是合理的说法每个 XAML 开发人员将使用数据绑定或大或小的程度上。虽然它可以是诱人的 (尤其是对于开发人员来自不支持这种机制的更多传统技术),一次处理大部分的数据模型更改在源代码中直接掌握了数据绑定的权力几乎不可能再去写在源代码中的数据更改管理的繁琐过程。
不仅仅是数据控件
XAML 数据绑定是为更多"只是"数据控件。它允许将任何对象的任何属性绑定到任何其他属性。(请记住只是属性的一种特殊称为依赖项属性 [DP] 可以是属性的数据绑定的目标。存款保障计划中不存在 Android 和 iOS,这就是为什么可用的数据绑定框架使用一些替代方法。)
数据绑定看到采用的框架,例如 KnockoutJS 和 AngularJS,功能在后台运行的 JavaScript 代码的数据绑定扩展 Web 世界的兴趣重燃。这些数据绑定框架重启发了 XAML 的框架,它是有趣的看到一大群人,采用的原则 (如 MVVM 模式),已由 XAML 社区。
一个声明的过程
像 XAML 和 HTML 标记技术被称为声明式的因为它们允许您为用户界面"宣布"你的意图。这是在不同时间点上比代码实现,通常做,有时甚至由不同的团队。例如,在 XAML 技术 UI 开发人员负责 XAML 被称为"集成"或有时"地产商的互动,"或甚至野蛮"devsigner"。此角色意味着设计师的视觉的应用程序,很好地理解,即使集成商往往是开发商,他们坐在两把椅子之间,应用程序开发中有较强的创新责任。
由于数据绑定中,有可能甚至在小型开发团队强烈区分 UI 创造的过程。当我工作的小应用程序,在那里我唯一开发商时,我想说我在开发过程中切换的帽子。当代码包括数据模型、 数据服务心的我工作时,我就穿我开发的帽子。当我切换到创建 UI 时,然后更改给我积分的帽子。
这种分离的角色反映了分离关注点,通常是可取的在现代软件开发中。虽然数据绑定并不绝对需要这种分离,它是非常方便的方法,帮助你进入正确的心态。
有 Xamarin 中的数据绑定吗?
就像在 Windows Phone Xamarin.Android 和 Xamarin.iOS 允许 UI,以建在源代码中直接,但也提供了一个更现代的方法与声明性标记中使用的 XML 文件。在 Android 中,这是一个 AXML 的文件 ; 在 iOS 中一种方便的方法是使用演示图板文件。这是类似于我们在 Windows Phone 与 XAML 中做了什么。注意到这些声明性标记文件并不特定于 Xamarin ; 它们也用香草的 Android 和 iOS 开发中。
虽然方便 (尤其是因为它们允许使用像 Xamarin Studio 中或在 Visual Studio 中提供的可视化设计器工具) 的声明性标记文件在 Android、 iOS 都比 XAML 不那么强大。尤其是,他们缺乏 XAML 所要求的标记扩展。这种表达式括在大括号 ({}) 内。有大量的这些扩展,例如,访问资源位于在 XAML 文档中或创建一个数据绑定,此代码片断所示:
<Button Content="{Binding ButtonContent}"
Command="{Binding ExecuteCommand}"
CommandParameter="{Binding IsChecked, ElementName=LockCheckBox}" />
此标记,是视图的一部分,说一个按钮控件已绑定到源属性称为 ButtonContent,其内容属性和其命令属性绑定到一个名为 ExecuteCommand 的源属性。这些源属性都可以在任何对象作为默认数据或绑定上下文为该按钮的父母 (通常是作为一个整体的页面) 通常 ViewModel 对象。但是,您可以在任何您需要的级别设置绑定上下文。第三行的标记,例如,明确它说,与此相应按钮绑定到另一个元素校正属性在页,它的名字叫 LockCheckBox。
不幸的是,并不存在的数据绑定概念本身在 Android 和 iOS 所以,在本文的其余部分,我将会向您展示如何可以实现这两个平台的数据绑定中的 Xamarin,然后如何 MVVM 光工具包提供了一种实现你可以使用来促进这一进程。此外,Xamarin 还提供了称为 Xamarin.Forms 的 ui 使用类似于 Windows 的 XAML 标记语言扩展。Xamarin.Forms 支持绑定声明标记中的直接,无需添加任何外部框架。
在 Android 和 iOS 中实现数据绑定
我要去构建一个小型的应用程序连接到一个简单的数据服务,并返回一个列表的花朵,每一个都有一个名称和描述。你会发现这种应用,名叫 XamDataBinding,在 galasoft.ch/s/xambinding。为简单起见,我将集中精力只,一页所示图 1。此页上,在 Android、 iOS 和 Windows Phone 中实现具有以下特点:
- 花一个列表。理想情况下列表应该更新本身只要底层数据源发生更改。
- 用于刷新列表的按钮。
- 文本显示的日期和上次刷新时间。
- "锁定"复选框或开关。此元素的目的相当不在生产场景中,但用于演示,有一定的道理,想象这"锁"的刷新按钮时它检查。
图 1 样品在 Android、 iOS 和 Windows Phone 中的应用
MVVM 模式依赖于一些简单的原则:
- 可观测对象实现 INotifyPropertyChanged 接口。此.NET 接口公开的引发事件,应可观察到的属性修改时引发。
- 可以在应用程序的过程中更改的列表应该存储在 ObservableCollection < T > 实例。
- 这样一份名单引发 CollectionChanged 事件时其内容发生更改 (添加、 删除或不同的排序顺序)。
- 某些对象公开功能的实现 ICommand 接口的属性。此接口定义一个 Execute 方法和 CanExecute 方法。后者返回 true 或 false,具体取决于是否可以执行的 Execute 方法。此外,ICommand 指定的 CanExecuteChanged 事件。因为这有可能影响到绑定的 UI 控件的状态,当 CanExecute 方法的变化,返回的值中必须会引发此事件。
在 MVVM 光工具包,这些接口是由具体的类,如 ObservableObject 和 ViewModelBase (INotifyPropertyChanged) 和 RelayCommand (ICommand) 实现的。在 XamDataBinding 示例中,建立使用 MVVM 光工具包,并存储在一个称为 XamDataBinding.Data 的便携式类库中进行的模型和 ViewModel 层。 此库可以 Xamarin 和窗口之间共享。
MVVM,在每个视图是"驱动"由 ViewModel。在 Windows 和 Windows Phone,ViewModel 通常用作该 DataContext,是一个属性视图 (页面、 窗口、 UserControl 等等)。这是一种简便方法使用数据绑定,而不必总是指定绑定的源。在 Android 和 iOS,那里是没有 DataContext 的概念。相反,您声明 ViewModel 视图中的并直接使用它。XamDataBinding 样品一样的小应用程序,可以直接在视图中创建 ViewModel (安卓系统,MainView 中的活动控制器在 iOS 和在 Windows Phone 主页):
private MainViewModel _vm;
public MainViewModel Vm
{
get
{
return _vm ?? (_vm = new MainViewModel());
}
}
执行具有约束力和指挥没有一个框架
若要避免在一遍遍重复同样的事情,我会在此集中的 XamDataBinding 样品的 Android 应用程序。然而,完全相同的概念适用于 iOS 应用程序。由于这些平台不支持数据绑定,我会执行绑定和手动指挥:
- 检查已更改的属性的名称和相应地更新视图,我会处理在视图中,MainViewModel 的引发事件。
- 某些绑定在两个方向 (双向绑定) 去。例如,当单击复选框时,在 MainViewModel 上相应的布尔属性需要更新。不具有约束力的框架,我需要订阅复选框事件和更新从视图中手动视图模型的属性。
- 刷新按钮必须在 MainViewModel 上执行 RefreshCommand。没有一个指挥的框架,这一点,也必须被手动处理。我可以处理该按钮的 Click 事件,并从视图中直接调用命令的执行方法。
- 最后,我知道该命令可以禁用它所绑定到的控件。在这种情况下,如果没有指挥的框架,我需要订阅的命令可以ExecuteChanged 事件。时触发此事件,可以调用该命令的 CanExecute 方法,根据返回的值,启用或禁用控件。
这些步骤都不是很复杂的但整个过程可以是冗长而重复。在实践中,很容易使用具有约束力和指挥的框架,如由 MVVM 光工具包提供。
使用 MVVM 光数据绑定框架
前面的示例中工作,但他们讨厌写,因为你必须处理的各项活动和思考的所有可能的方案。它们也是更难维护和理解,尤其是当有多个 UI 元素来处理。
简单的数据绑定框架中使用 MVVM 光工具包,与此相反的是,允许您创建 UI 元素和代码,以及用户界面元素和命令之间的关系。由于此绑定框架下,可以创建绑定并附加到命令在 OnCreate 方法中,如中所示图 2。
图 2 创建绑定和命令
_lastLoadedBinding = this.SetBinding(
() => Vm.LastLoadedFormatted,
() => LastLoadedText.Text);
_lockBinding = this.SetBinding(
() => Vm.IsLocked,
() => LockCheckBox.Checked,
BindingMode.TwoWay);
_refreshCommandBinding = this.SetBinding(
() => LockCheckBox.Checked);
RefreshButton.SetCommand("Click", Vm.RefreshCommand, _refreshCommandBinding);
FlowersList.Adapter = Vm.Flowers.GetAdapter(GetFlowerAdapter);
在图 2,第一次创建 MainViewModel 的 LastLoadedFormatted 属性和 TextView 的 Text 属性之间的单向绑定。这种单一的代码行照顾建立这两个属性之间的长期关系。注意,使用扩展方法将绑定,这由 MVVM Light 提供。此方法返回创建的绑定实例。因为绑定对象用 WeakReferences 以避免内存泄漏编写的这种绑定应保存为一个私有字段来防止绑定获取自动分离。
第二个语句创建的 MainViewModel 的 IsLocked 属性与 LockCheckBox 选中的属性之间的双向绑定。请注意默认情况下,每个绑定都是单向的所以您必须指定双向 BindingMode 将绑定方法中。
第三个语句创建一种特殊的约束力,只有源与没有目标。来自 LockCheckBox 的检查的属性。我会在 SetCommand 方法中,使用此绑定,以指示 MainViewModel LoadCommand 应该被重新评估,每次 LockCheckBox 选中的属性更改时。在 XAML 中,我将创建一个绑定在与此相应的按钮上。在这里,我使用一个类似的构造由创建绑定第一,,然后将此实例传递给 SetCommand 方法。
第四条语句上的 RefreshButton 设置的命令。虽然我处理 Click 事件在这里,我其实可以开动任何 UI 元素的任何事件的命令。SetCommand 方法的第二个参数是必须驱动的命令。最后,第三个参数是可选的仅用于需要参数的命令。如前所述,我在这里使用前面创建的绑定。
正在设置列表
最后,还有 ListView 在 UI 中。MVVM Light 提供一种称为 GetAdapter,可以使用在任何 ObservableCollection 或任何 IList 上的非常有用的扩展方法。它返回一个 Android 的适配器,可以用作 ListView 适配器属性。因为 MainViewModel 花属性是 ObservableCollection,集合发生更改时将自动更新用户界面:
FlowersList.Adapter = Vm.Flowers.GetAdapter(GetFlowerAdapter);
GetFlowerAdapter 方法,传递给 GetAdapter 方法时,用于获取行认为,将代表一朵花。在这个例子中我把它简单通过使用一个内置行视图,以显示图片和花的名字图 3 显示。不过,我们会很容易的要使用更多的细节或不同的布局来创建自定义行视图。
如果我运行该应用程序现在,我会看到用户界面中显示图 1。您可以尝试以下功能:
- 单击锁定复选框将禁用刷新按钮。禁用通过 RefreshCommand 和 CanExecute 方法发生。检查 MainViewModel 的代码,看看如何做到这一点。请注意同样的效果会在 XAML 中,是否您运行包含的 Windows Phone 应用程序。
- 启用刷新按钮后,单击它异步加载列表中的花朵。注意连接到 Web 服务的代码包含在 MainViewModel,并在此可移植类库支持任何平台上完全可以重复使用。
- 加载列表后,将与"最后加载"信息更新的 TextView 状态。这,也是通过我创建的绑定。
- 运行 iOS 或 Windows Phone 版本的应用程序创建完全相同的结果。在 iOS,在 MainViewController 的 ViewDidLoad 方法中创建绑定。在 Windows Phone,我创建了 MainPage.xaml 中的绑定。
图 3 创建自定义的列表视图行
private View GetFlowerAdapter(
int position,
FlowerViewModel flower,
View convertView)
{
if (convertView == null)
{
convertView = LayoutInflater.Inflate(
Android.Resource.Layout.ActivityListItem, null);
}
var text = convertView.FindViewById<TextView>(Android.Resource.Id.Text1);
text.Text = flower.Model.Name;
var image = convertView.FindViewById<ImageView>(Android.Resource.Id.Icon);
image.SetImageBitmap(GetImageBitmapFromUrl(flower.ImageUri.AbsoluteUri));
return convertView;
}
Xamarin.Forms 中的数据绑定
去年,Xamarin 发布的形式框架,允许共享代码,也是 UI 中所有支持的平台。这是理想的建设快速的用户界面测试的代码 ; 例如,在原型阶段。窗体框架也可以用于生产代码例如,必须在多个平台上运行的业务线应用程序。
与 Xamarin.Android 和 Xamarin.iOS,Xamarin.Forms 支持数据绑定本机。因为它还支持 XAML (虽然比在 WPF,Windows Phone 和 Windows 应用商店中可用的不同版本),可以直接写在 XAML 标记中的数据绑定。这意味着您可以编写这样的事情:
<Label Text="{Binding LastLoadedFormatted}"
VerticalOptions="Center"
HorizontalOptions="Center" />
所包含的示例可以通过使用 Xamarin.Forms 和重用每个平台上的用户界面更加简化。当然,对于应用程序在哪里与用户体验必须采取额外的照顾,Xamarin.Forms 可能不是最佳的解决方案。但是,应用程序的整个范围,窗体将 UI 开发大大简化,释放你处理其他任务,如提高应用程序的性能和稳定性,添加功能,等等。
结束语
MVVM Light 绑定有别于 XAML 绑定在它们创建代码而不是标记中。但是,确保干净的 API,花费了好几个小时。我借此机会感谢我的好朋友科拉多沃利上绑定实现的支持和帮助我创造一种尽可能接近到 XAML 绑定工作流的语法。
此外,对于他们的帮助,我要感谢 Xamarin 乘员组和特别是 James Montemagno 审查此绑定框架的早期版本,给了我超级宝贵的意见。
最后,为更多的信息和一个完整代码示例,包括 Windows Phone、 Xamarin.Android、 Xamarin.iOS 和 Xamarin.Forms,看看我 Xamarin 演变的演示文稿,在 galasoft.ch/s/evolve14。
Laurent Bugnion 是使用 WPF、 Silverlight,Xbox,Kinect,Windows 应用商店、 Windows Phone、 Xamarin 和体验等技术的 Microsoft 合作伙伴 IdentityMine 公司的高级主管他设在瑞士的苏黎世。他也是微软最有价值球员、 微软区域主任和 Xamarin MVP。
衷心感谢以下技术专家对本文的审阅:克赖希 Brockschmidt (Microsoft) 规范埃斯 (Microsoft) 和 James Montemagno (Xamarin)