<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>使用CSS将Div固定在窗口的右下角</title> <style> #INDEXT_RB_AD{ clear:both; width:200px; height:100px; z-index:1000; overflow:hidden; border:1px #ccc solid; bottom:5px; right:5px; /* 火狐、Google浏览器只需要后面这一句代码即可 */ position:fixed !important; /* 以下代码是针对IE6的 */ _position:absolute; _top: expression( eval( document.documentElement.scrollTop + document.documentElement.clientHeight - this.offsetHeight - (parseInt(this.currentStyle.marginTop,10)||0) - (parseInt(this.currentStyle.marginBottom,10)||0) ) - (parseInt(this.currentStyle.bottom,10)||0) ); } </style> </head> <body> <div >使用CSS将Div固定在窗口的右下角</div> <div id="INDEXT_RB_AD" > <div align="right" onclick="document.getElementById('INDEXT_RB_AD').style.display = 'none';">关闭</div> <div>这里是您要显示的内容</div> </div> </body> </html> ======================================================================= 如果要将该功能写入js文件里,供网站多个页面同时调用,可以使用下列代码 ======================================================================= <script> //var RB_FLOAT_AD = "no"; //在不需要显示的页面加上此行代码 if ( typeof(RB_FLOAT_AD) == "undefined" || RB_FLOAT_AD != "no" ){ //输出CSS样式 document.write('<style>#INDEXT_RB_AD{ clear:both; width:200px; height:100px; z-index:1000; overflow:hidden; border:1px #ccc solid; bottom:10px; right:5px; /* 火狐、Google浏览器只需要后面这一句代码即可 */ position:fixed !important; /* 以下代码是针对IE6的 */ _position:absolute; _top: expression( eval( document.documentElement.scrollTop + document.documentElement.clientHeight - this.offsetHeight - (parseInt(this.currentStyle.marginTop,10)||0) - (parseInt(this.currentStyle.marginBottom,10)||0) ) - (parseInt(this.currentStyle.bottom,10)||0) ); }</style>'); // document.write('<div id="INDEXT_RB_AD" ><div align="right" onclick="document.getElementById('INDEXT_RB_AD').style.display = 'none';">关闭</div><div>这里是您要显示的内容</div></div>'); } </script>
MVVM模式的View与ViewModel的三大通讯方式:Binding Data(实现数据的传递)、Command(实现操作的调用)和Attached Behavior(实现控件加载过程中的操作)。
这里再谈一下textbox双向绑定的问题以及绑定行为的一些东西。
一、textbox双向绑定取值异常问题:
就比如说这个textbox:
<TextBox Text="{Binding Mobile, Mode=TwoWay}" BorderBrush="{StaticResource PhoneAccentBrush}" Background="{StaticResource PhoneBackgroundBrush}"/>
很明显是个双向绑定的数据模式,我们在看后端vm代码
public void SubmitAction() { if (!this.ValidateData()) return; App.LwApi.GetInternalService().BindMobile(this.Mobile, this.Code, (o, ev) => { if (ev.Error != null) { MessageHandleHelper.HandleError(ev.Error); return; } MessageBox.Show("手机号绑定成功!"); NavigationController.GoBack(); }); }
上述代码在提交命令触发时调用,这里有一个很奇怪的现象:当我们直接触发点击事件时,是无法同步的享有Mobile属性的值的,只有在用户再对textbox失焦后才能正常的。
这里的原因在于wp系统只在当前textbox触发LostFocus事件后才会对绑定的数据赋值。现在我们就需要将事件触发提前到每一次的TextChanged事件里进行触发。
将代码改成:
<TextBox Text="{Binding Mobile, Mode=TwoWay, UpdateSourceTrigger=Explicit}" TextChanged="OnPhoneTextBoxTextChanged" BorderBrush="{StaticResource PhoneAccentBrush}" Background="{StaticResource PhoneBackgroundBrush}"/>
注意上面的 UpdateSourceTrigger 属性:TwoWay是由绑定目标到绑定源方向,若实现绑定目标的值更改影响绑定源的值方式,只需要设置相应控件绑定时的UpdateSourceTrigger的值,其值有三种:1、PropertyChanged:当绑定目标属性更改时,立即更新绑定源。2、 LostFocus:当绑定目标元素失去焦点时,更新绑定源。3、 Explicit:仅在调用 UpdateSource 方法时更新绑定源。 多数依赖项属性的UpdateSourceTrigger 值的默认值为 PropertyChanged,而 TextBox 属性的默认值为 LostFocus。
我们现在把它设置为Explicit的意思就是要在cs文件里手动调用UpdateSource 方法才会更新绑定源数据。cs代码如下:
private void OnPhoneTextBoxTextChanged(object sender, TextChangedEventArgs e) { TextBox ptb = sender as TextBox; BindingExpression be = ptb.GetBindingExpression(TextBox.TextProperty); be.UpdateSource(); }
上面的代码就是手动调用更新绑定源的操作。
现在我们可以看到viewmodel层已经可以正确的操作属性了。
下面我们再看一下附加行为方式的解耦:
二、LongListSelector的回到顶部功能的Attached Behavior方式实现
回到顶部的功能其实在codebehind代码里写起来异常的简单:只需一句ScrollTo就能轻松搞定,但我们的业务代码全部写在Viewmodel中,比如我们执行了refreshData的操作,要求list回到顶部,如果ScrollTo写在cb代码里,我们就必须要用notification方式去实现,然而这种方式既会搞得代码很复杂而且后期维护的成本也很大。(不要问我那为什么要把业务代码写vm里。。。vm里写业务代码能使得前端UI修改方便,而且移植起来也方便,甚至我们的win8 app就直接能套用wp的业务vm代码)
为了使这里我们要用到第三种解耦模式:Attached Behavior方式也就是行为依赖的方式。我们会写一个ToTop的Behavior类。这里先看它的调用方式:
<toolkit:LongListSelector x:Name="StoryListBox" Background="Transparent" ShowListHeader="False" ShowListFooter="False" IsFlatList="True" BufferSize="5.0" lwcontrols:ToTopBehavior.GoTop="{Binding GoTopFlag, Mode=TwoWay}" ItemsSource="{Binding StoryList}" ItemTemplate="{StaticResource StoryTemplate}" />
看到这一句: lwcontrols:ToTopBehavior.GoTop="{Binding GoTopFlag, Mode=TwoWay}"这个就是Behavior的xml绑定方式;
再来看vm:
private bool goTopFlag; public bool GoTopFlag { get { return goTopFlag; } set { goTopFlag = value; this.RaisePropertyChanged("GoTopFlag"); } } public override void RefreshData(Action<object> callback = null) { base.RefreshData((o) => { GoTopFlag = true; callback.Invoke(o); }); }
是的,我们需要一个双向绑定的属性,在vm中直接调用 GoTopFlag = true;就能使list直接回到顶部;看是如何做到的(ToTopBehavior.cs):
namespace Laiwang.Controls { static public class ToTopBehavior { public static readonly DependencyProperty GoTopProperty = DependencyProperty.RegisterAttached( "GoTop", typeof(bool), typeof(ToTopBehavior), new PropertyMetadata(new PropertyChangedCallback(OnGoTopChanged))); public static bool GetGoTop(DependencyObject obj) { return (bool)obj.GetValue(GoTopProperty); } public static void SetGoTop(DependencyObject obj, bool value) { obj.SetValue(GoTopProperty, value); } private static void OnGoTopChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { LongListSelector control = obj as LongListSelector; if (control != null) { if ((bool)args.NewValue) { ScrollViewer scrollViewer = CommonHelper.FindChildOfType<ScrollViewer>(control); if (scrollViewer.VerticalOffset > 1) { object o = null; foreach (var item in control.ItemsSource) { if (item == null) return; o = item; break; } control.ScrollTo(o); } } } SetGoTop(control, false); } } }
像给依赖对象附加依赖属性一样,我们这里只是对一个已有的依赖对象附加一个新的依赖属性:GoTop,我们所有的操作都是在OnGoTopChanged事件做的,事实上我们这个方法是对双向模式中的PropertyChangedCallback,还记得一般的双向的UpdateSourceTrigger都是PropertyChanged吗,对于依赖属性也是这样的。我们只是简单的判断了 if ((bool)args.NewValue)并作出回滚的实现,注意后面我们又调用了SetGoTop(control, false),这样做很明显就是让它下一次的赋值为true时能执行刚才的代理事件。
vm和view的解耦虽说感觉是简单的事情复杂化了,但不管怎么说,这样做的好处也显而易见的,维护的成本降低了,wp和win8的移植也变的如此的简单美妙,只需对view层更改及简单的vm更改就能轻松搞定,ms这一套wpf的东西还是非常值得借鉴的。嗯,wp8我还是非常期待啊。。。
另外,近些天一直在做的ios开发对于事件的绑定及回调都是用delegate去做,感觉非常的麻烦。试图改变这种情况,貌似ios中KVO以及block的使用会改进这些,待我研究研究。。。
git 是版本控制工具
安装方法:
sudo apt-get install git git-core
更新方法:
git clone git://git.kernel.org/pub/scm/git.git
创建一个版本库
git-init-db 完成后在当前目录创建一个.git的目录
ls -a可以查看到一个叫HEAD的文件,其中内容为:ref: refs/heads/master
===============================================================
安装rpm
sudo apt-get install rpm
查看自带jdk版本
rpm -qa | grep gcj
安装java jdk
下载jdk-6u30-linux-x64.bin
mkdir java
./jdk-6u30-linux-x64.bin
文件安装在/usr/java/jdk1.6.0_30
建立一个软连接
ln -s /usr/java/jdk1.6.0_30 /usr/jdk
编辑配置文件
vi /etc/profile
添加
JAVA_HOME=/usr/jdk
CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASSPATH
#source /etc/profile
#java -version
依赖的其它包
sudo apt-get install flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-
dev build-essential zip curl
调试工具
sudo apt-get install valgrind
在当前用户目录retacnyue
下载repo工具
mkdir ~/bin
PATH=~/bin:$PATH
(也可手动下载)
curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
chmod a+x ~/bin/repo
初始化一个repo客户端
mkdir myandroid
cd myandroid
下载主线分支
repo init -u https://android.googlesource.com/platform/manifest
下载android 源码
repo init -u https://android.googlesource.com/platform/manifest -b
android-4.0.1_r1
查看repo的初始化信息
ll
同步代码
repo sync
建立本地代码分支
在源码的根目录下
git --git-dir .repo/manifests/.git/ branch -a
问题:
error: Exited sync due to fetch errors
方法:
1 https://accounts.google.com/ServiceLogin?
service=lso&continue=https://accounts.google.com/o/oauth2/auth?scope%
3Dhttps://www.googleapis.com/auth/gerritcodereview%26response_type%
3Dcode%26redirect_uri%3Dhttps://www.googlesource.com/new-password%
26state%3Dandroid%26client_id%3D413937457453.apps.googleusercontent.com%
26hl%3Dzh-CN%26from_login%3D1%26as%3D-
3b0efc6a0a50a9e0<mpl=popup&shdf=CoQBCxIRdGhpcmRQYXJ0eUxvZ29VcmwaAAwLEhV0
aGlyZFBhcnR5RGlzcGxheU5hbWUaEiouZ29vZ2xlc291cmNlLmNvbQwLEgZkb21haW4aEiouZ2
9vZ2xlc291cmNlLmNvbQwLEhV0aGlyZFBhcnR5RGlzcGxheVR5cGUaB0RFRkFVTFQMEgNsc28i
FI_kJIk4Sm8kys37XvaeuJ6iqzzHKAEyFIOiXsMNAaLtwz6ZVNKzbwfz4IyV&scc=1&authuse
r=0
2 以machine开头的两行复制到 ~/.netrc文件中(.netrc文件是在用户的根目录下)
machine android.googlesource.com login git-loveyou.for.ever.163.com
password 1/Jt3XbnabXVBBDZI3TzZWSVTXu_SqC5kh_-hbqMjtnbQ
machine android-review.googlesource.com login git-loveyou.for.ever.163.com
password 1/Jt3XbnabXVBBDZI3TzZWSVTXu_SqC5kh_-hbqMjtnbQ
3 repo init -u https://android.googlesource.com/a/platform/manifest
或repo init -u https://android.googlesource.com/a/platform/manifest -b
android-4.0.1_r1
4 repo sync
====================================================================
开发环境的搭建
samba环境搭建
安装samba和smbfs
sudo apt-get install samba
sudo apt-get install smbfs
创建共享文件夹
mkdir /home/retacnyue/share
chmod 777 /home/retacnyue/share/
备份并编辑smb.conf允许网络用户访问
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf_backup
sudo gedit /etc/samba/smb.conf
修改
# security = user
security = user
username map = /etc/samba/smbusers
添加
[share]
path = /home/retacnyue/share
available = yes
browsealbe = yes
public = yes
writable = yes
找到workgroup = WORKGROUP添加
display charset = UTF-8
unix charset = UTF-8
dos charset = cp936
添加用户
sudo useradd retacnyue
sudo smbpasswd -a retacnyue
密码
123456
文件中添加
nancy = "network username"
删除帐号的命令把 -a改为-x
=======================================================
xp中应射共享目录
。。。
==========================================================