NGUI 学习笔记实战之二——商城数据绑定(Ndata)
上次笔记实现了游戏商城的UI界面,没有实现动态数据绑定,所以是远远不够的。今天采用NData来做一个商城。
如果你之前没看过,可以参考上一篇博客
NGUI 学习笔记实战——制作商城UI界面
http://www.cnblogs.com/chongxin/p/3876575.html
一、NData介绍以及优点
大体来说NData就是一个NGUI 的 MVVM 框架插件,如果你问我什么是MVVM,我也只能说类似于MVC,至于什么是MVC…………
说道NData的优点,我们先来看这个,如果要写商城逻辑,一般如下:
这个逻辑很简单,但是之前我实现是在OnMouse这类函数中进行判断,然后直接与底层数据交互。这还没什么,如果底层商城的商品种类增加,那么我还得在UI进行构造新的UI部件。
最后,让我无法容忍的就是,这些UI部件的显示的数据我还要记住这些UI部件的路径,一个个翻过去找,如果路径复杂就很麻烦。刚开始还没什么,时间一长就要吐了。
这些用NData就可以很方便的解决,大体的解决思路就和上面那张图差不多,他在UI和逻辑层中又多加了一层,类似于页面逻辑模型,并且将页面逻辑模型的数据和显示UI上的部件绑定。做到了动态刷新。
之后你对页面所有的操作都可以通过对这个页面模型交互来实现,做到了逻辑和UI分离的境界。
二、创建ViewModel模板
可能你看的刚才云里雾里,那么你可以省略刚才那段话,更多的时候领悟是在实践中才发现。
我们现在先编写一个页面模型,模板如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
using UnityEngine; public class $game$Ui : EZData.Context { //TODO: add your dependency properties and collections here //绑定页面上的属性 #region Property $name$ private readonly EZData.Property<$type$> _private$name$Property = new EZData.Property<$type$>(); public EZData.Property<$type$> $name$Property { get { return _private$name$Property; } } public $type$ $name$ { get { return $name$Property.GetValue(); } set { $name$Property.SetValue(value); } } #endregion //绑定页面上的集合(比如商城每一行) #region Collection $name$ private readonly EZData.Collection<$type$> _private$name$ = new EZData.Collection<$type$>( false ); public EZData.Collection<$type$> $name$ { get { return _private$name$; } } #endregion } public class ViewModel : MonoBehaviour { //NGUI UIRoot 编辑器中手动拖进<br> public NguiRootContext View; //这个代表页面模型<br> public $game$Ui Context; void Awake() { Context = new $game$Ui(); View.SetContext(Context); } } |
对于上面的模板,如果对其功能有所疑问的话,我建议你看一下NData 的基本教程http://tools.artofbytes.com/ndata/tutorials/simple-tutorial,其实功能我在代码注释中已经写的很明白了。
这里有一个小插曲,看NData的官方教程是用Mono的类模板来创建 ,因为本人Win7下开发,装了VS2010, 装了之后却用不了mono了,无语。
三、页面逻辑编写
这里我们要实现的页面功能如下:
可以看到,我们这里的商城类似于表格,有多行3列,同时每一个UI部件也有自己属性,设计页面模型如下:
UI部件的页面模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class CommodityItem : EZData.Context { #region Property ShopId #endregion #region Property Name #endregion #region Property Price #endregion //商品图标 #region Property Logo #endregion #region Property Describle #endregion } |
每行的页面模型
1
2
3
4
5
6
7
8
9
|
public class CommodityPage<T> : EZData.Context where T : EZData.Context { //列的集合 #region Collection Page private readonly EZData.Collection<T> _privatePage = new EZData.Collection<T>( false ); public EZData.Collection<T> Page { get { return _privatePage; } } #endregion } |
整体的模型
1
2
3
4
5
6
7
8
9
10
|
public class Shop<T> : EZData.Context where T : EZData.Context { //行的集合 #region Collection Table private readonly EZData.Collection<CommodityPage<T>> _privateTable = new EZData.Collection<CommodityPage<T>>( false ); public EZData.Collection<CommodityPage<T>> Table { get { return _privateTable; } } #endregion } |
四、页面模型进行数据填充
一、先设计一个内存数据库,填充每一个UI部件页面模型的数据
二、页面模型进行引用填充,填充行列的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
public class Shop<T> : EZData.Context where T : EZData.Context { //行的集合 #region Collection Table private readonly EZData.Collection<CommodityPage<T>> _privateTable = new EZData.Collection<CommodityPage<T>>( false ); public EZData.Collection<CommodityPage<T>> Table { get { return _privateTable; } } #endregion //页面模型生成的时候 同时进行数据绑定 public Shop(T[] Array, int PageNum) { Load(Array,PageNum); } //加载数据 void Load(T[] Array, int PageNum) { //总共需要的数量 int AllNum = Array.Length; //每一页需要的数量 int PageCount; //有多少页 if (AllNum == 0) PageCount = 0; else PageCount = ((AllNum % PageNum == 0) ? (AllNum / PageNum) : (AllNum / PageNum + 1)); //总有多少行 for ( int i = 0; i < PageCount; i++) { //生成一行 Table.Add( new CommodityPage<T>()); //总有多少列 for ( int j = 0; j < PageNum && (i * PageNum + j) < AllNum; j++) { Table.GetItem(i).Page.Add(Array[i * PageNum + j]); } } } } public class UIShopViewModel: MonoBehaviour { public NguiRootContext View; public Shop<CommodityItem> Context; public ShopData myShopDate; void Awake() { Context = new Shop<CommodityItem> (myShopDate.CommodityItemArray,3); View.SetContext(Context); } } |
三、数据绑定
到了最重要的一步,进行数据绑定。刚才的页面逻辑如果你跟下来的话就知道我们首先要设计一个UI部件 之后三个组成一行,然后多行组成一个界面
如此,我们先绑定UI部件
再绑定一行
最后绑定整个页面
最后、动态生成
测试一下:数据库里面新加一条
UI商城可以动态增加,完全代码操作,动态刷新,只需要加一句话。
整体的流程就是设计页面模型,填充页面模型数据,绑定页面,方便快捷有保证,而且可以复用,之后类似的界面,只需要换掉最基本的UI页面模型即可。哇咔咔!
2014-9-3 记录: 注意,商品部件也就是item 中的 图片动态绑定是有问题的,不论用texturebind 还是spritebinding.最后只会出现一张图片
我建议自己根据NguiItemDataContext 得到对应的 行列index, 然后在viewmodel中找到对应的那个部件的图片名称,然后根据图片名称自己查找图片赋值。
Ndata基本上已经不更新了,而且bug很多,在做复杂业务逻辑的时候要注意。
2014-9-4 问题解决
NguiTextureBinding 本质是用uitexture 的 材质的图片,而材质是只有一个的,除非你每个item用一个材质,如果你都用一个材质,那么所有item的图片取决于你最后的那个材质所用的图片,这样也就解释了为什么texturebind只会出现一张图片。
更新如下即可:
2014-9-22日
注意,在用grid 进行NguiItemsSourceBinding 使用Path 绑定的时候,NguiListItemTemplate的Template的gameobject root 最好是带有碰撞器的,不然无法使用 **list.selecteditem
NGUI 学习笔记实战之二——商城数据绑定(Ndata)的更多相关文章
- NGUI 学习笔记实战——制作商城UI界面
http://www.cnblogs.com/chongxin/p/3876575.html Unity3D的uGUI听说最近4.6即将推出,但是目前NGUI等UI插件大行其道并且已经非常成熟,所以我 ...
- WPF学习笔记:(二)数据绑定模式与INotifyPropertyChanged接口
数据绑定模式共有四种:OneTime.OneWay.OneWayToSource和TwoWay,默认是TwoWay.一般来说,完成数据绑定要有三个要点:目标属性是依赖属性.绑定设置和实现了INotif ...
- NGUI学习笔记汇总
NGUI学习笔记汇总,适用于NGUI2.x,NGUI3.x 一.NGUI的直接用法 1. Attach a Collider:表示为NGUI的某些物体添加碰撞器,如果界面是用NGUI做的,只能这样添加 ...
- 【Unity Shaders】学习笔记——SurfaceShader(二)两个结构体和CG类型
[Unity Shaders]学习笔记——SurfaceShader(二)两个结构体和CG类型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5596698. ...
- Linux进程间通信IPC学习笔记之同步二(SVR4 信号量)
Linux进程间通信IPC学习笔记之同步二(SVR4 信号量)
- Linux进程间通信IPC学习笔记之同步二(Posix 信号量)
Linux进程间通信IPC学习笔记之同步二(Posix 信号量)
- VSTO 学习笔记(十二)自定义公式与Ribbon
原文:VSTO 学习笔记(十二)自定义公式与Ribbon 这几天工作中在开发一个Excel插件,包含自定义公式,根据条件从数据库中查询结果.这次我们来做一个简单的测试,达到类似的目的. 即在Excel ...
- Unity3d之Hash&Slash学习笔记之(二)--角色基础类的构建
Hash&Slash学习笔记之(二)--角色基础类的构建 BaseStat类的构建 基本成员变量: _baseValue //基础属性值 _buffValue //增加的buff值 _expT ...
- 汇编入门学习笔记 (十二)—— int指令、port
疯狂的暑假学习之 汇编入门学习笔记 (十二)-- int指令.port 參考: <汇编语言> 王爽 第13.14章 一.int指令 1. int指令引发的中断 int n指令,相当于引 ...
随机推荐
- Mustache.js前端模板引擎源码解读
mustache是一个很轻的前端模板引擎,因为之前接手的项目用了这个模板引擎,自己就也继续用了一会觉得还不错,最近项目相对没那么忙,于是就抽了点时间看了一下这个的源码.源码很少,也就只有六百多行,所以 ...
- Java学习笔记(十七)——java序列化
[前面的话] 做项目总是要用到很多东西,遇到一个新的知识,并不是这个知识出来的时间短,而是对于自己来说是新的,所以就需要自己去学习,希望今后可以提高学习的效率. 这篇文章是关于Java 序列化的,选择 ...
- PDA设备小知识--(IP)工业防护等级含义
IP(INTERNATIONAL PROTECTION)防护等级是专门的工业防护等级,,它将电器依其防尘.防湿气之特性加以分级.IP防护等级是由两个数字所组成,第1个数字表示电器离尘.防止外物侵入的等 ...
- Moqui学习之代码分析mantle priceServices.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- This software is in the pub ...
- webform中的验证控件及两个应用技巧
一.非空验证--RequiredFiledValidator <一>属性: ErrorMessage--验证出错后的提示信息 ControlToValidate--要验证的控件的ID Di ...
- 使用NHibernate实现存储库
ORM框架不是存储库.存储库是一种架构模式,而ORM是将数据模型表示成对象模型的一种手段. 存储库可以使用ORM来协助充当领域模型和数据模型之间的中介. NHibernate允许在不损坏或只少量损坏领 ...
- grunt安装_
grunt_构建WEBJS程序框架,. package.json是文件配置 ====〉〉〉〉 在Gruntfile.js里面会引用到. //目录下直接放node的东西 ,比如: node_module ...
- Java设计模式-模板方法模式(Template Method)
解释一下模板方法模式,就是指:一个抽象类中,有一个主方法,再定义1...n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用,先看个关系 ...
- Java算法-快速排序
快速排序也是用归并方法实现的一个“分而治之”的排序算法,它的魅力之处在于它能在每次partition(排序算法的核心所在)都能为一个数组元素确定其排序最终正确位置(一次就定位准,下次循环就不考虑这个元 ...
- 解决SSH无密码登陆后又需要密码登陆
主节点CentOS_Master 从节点Slave_1. 我想着可能是 /etc/ssh/sshd_config下的那个公钥文件路径不对,看了下home/hxsyl/.ssh/authorized_k ...