最近和一个朋友合作一个来电归属和防火墙类应用(用了小部分NativeHack,都是那位朋友搞定的)。因为要读取本地联系人然后显示,为了便于分组显示。我没有使用Filter,而是直接获取全部联系人列表,然后去Map首字母。

    这样执行起来效率很低,毕竟是托管代码。但是期间为了转换成拼音还是费了点事,不仅找了徐老湿博客,还翻看了很多编码方面的东西,最后总结,汉字编码其实和拼音没啥太大关系。徐老湿推荐了一个GB2312的Encoding,然后通过码表查出汉字的码来获取拼音首字母,总的来说这其实不是一个很科学的做法,因为GB2312的编码前部分地确实按拼音来,可是后面的编码就不是了。因此很多汉字还是没法查询出来,而且GB2312只有6k多个汉字,我觉得不是很靠谱。然后找到了微软之前提供的Visual Studio International Pack,不过那个是给.Net Framework 用的。Windows Phone上显然用不了,于是我小小的利用了下Reflector,然后提取资源文件(其实就是一个字典),修改移植到了Windows Phone平台。

    测试了下,效率不是很高。调用系统api读取所有联系人,大概300个,然后每个联系人获取拼音首字母,总共耗时大概接近5秒。虽然平均下来似乎不慢,但是这个速度还是很令人郁闷的,于是我决定生成Local Database然后测试一次。

    测试完毕,数据库查询一样的慢,我很奇怪,这简直太没道理了,准备优化下,做个单独查询拼音的出来。先放出代码吧,需要的请自由下载,转载自觉注明出处。很希望大家提供更高效的解决方案。

http://vdisk.weibo.com/s/3JsL1

posted @ 2012-04-03 03:19 akita 阅读(43) 评论(1) 编辑

Windows phone 本身提供了很多的界面资源。

参照http://msdn.microsoft.com/en-us/library/ff769552(v=vs.92).aspx

今天要说的是怎么好好利用他们。

首先交代一个很基础但是一直被忽视的小Tip

 

一,关于中文等线字体的使用

我们知道Mango以来,WP是支持原生中文显示的,只要你可以把系统的Display Language改成中文。

你就可以使用等线字体,也就是系统显示的字体。否则默认会给你显示那个畸形的没经过优化GDI渲染的雅黑。

但有个问题是为什么我的软件默认language设置成了zh-CN,系统资源里的PhoneFontFamilyNormal却还是雅黑?

这个问题我考虑了很久,甚至更改默认的PhoneApplicationPage Style把字体改成DengXian。

但是这个不是解决问题的根本办法。因为这样英文字体也会用DengXian显示出来,效果是非常畸形的。

那么要怎么像系统一样英文继续使用英文字体,而中文用等线显示呢。

其实很简单,只要更改控件相应的Language属性就可以了。

更改了Language之后,所有的StaticResource资源会指向你设置的Language对应的资源。

例如我把某个Control的Language设置成zh-CN后,这个Control里面设置的PhoneFontFamilyNormal就是中文等线,英文Tahoma了。

知道了这个以后就很简单了,改变这一切就一句话。在App.xaml.cs.里面:

// Do not add any additional code to this method->不要理系统给的这句xx注释。。。 
private void InitializePhoneApplication()
{
// 其他代码忽略了…
RootFrame = new PhoneApplicationFrame()
{
Language = System.Windows.Markup.XmlLanguage.GetLanguage(System.Globalization.CultureInfo.CurrentCulture.Name)
};
// 其他代码忽略了…
}

然后,看看你的界面。多爽的等线字体!(虽然在白色背景下会发虚)

自动调配中文等线显示,英文Tahoma(系统原装)!

 

二,利用系统资源调配应用的主题配色

好吧我承认我坑爹了。。。我自己对OpacityMask都不太懂。等我研究会儿~哈。

posted @ 2011-12-03 20:12 akita 阅读(160) 评论(1) 编辑

我们知道MVVM模式是SL和WP开发一种很重要的模式。

其宗旨是将View和Model分离。可是,这之间还是有少量的问题。比如说我们有时候还是需要一些界面的反馈等等。

 

一,页面导航事件

 

首先我们来谈谈页面导航事件。

WP里面页面导航事件的触发用得比较多的是OnNavigatedTo和OnNavigatedFrom。

这两个属于Page类的一个可重载函数。PhoneApplicationPage是继承的Page所以可以重写这两个函数。

如果不是采用MVVM模式的话,我们可以很容易的在这两个方法里面写一些例如处理QueryString的代码。

但是采用MVVM之后,VM里面没发获取导航事件的触发,也没法获取QueryString了。

 

很多朋友愿意用Messenger或Event之类的机制来处理这个问题,可是我个人还是比较喜欢直观的函数调用的形式。

那么我们怎么在ViewModel里面接收到页面导航的事件呢。

首先,我们建立几个辅助的类别。

一个标志接口:INavigationBase,只是用来继承的。

两个派生接口:

public interface INavigatedViewModel : INavigationBase 
{
void OnNavigatedTo(NavigationEventArgs e);
void OnNavigatedFrom(NavigationEventArgs e);
}

public interface INavigatingViewModel : INavigationBase
{
void OnNavigatingFrom(NavigatingCancelEventArgs e);
}

一个用来Hook两个OnNavigated,另一个用来Hook OnNavigatingFrom。

建立一个NavigationController类。在RootFrame新建时将其初始化即可。

初始化时候最好做成Singleton形式。我自己是做成静态属性放在ViewModelLocator里面初始化的。

public class ViewModelLocator
{
private static NavigationController _navController;

public static void Init(PhoneApplicationFrame frame)
{
_navController = new NavigationController(frame);
}
}
public App()
{
// Global handler for uncaught exceptions.
// Note that exceptions thrown by ApplicationBarItem.Click will not get caught here.
UnhandledException += Application_UnhandledException;

// Standard Silverlight initialization
InitializeComponent();

// Phone-specific initialization
InitializePhoneApplication();

ViewModelLocator.Init(RootFrame);
}

NavigationController类部分代码如下:

private INavigationBase _currentVM; 
public NavigationController(PhoneApplicationFrame frame)
{
frame.Navigated += onRootFrameNavigated;
frame.Navigating += onRootFrameNavigating;
frame.NavigationFailed += onRootFrameNavigationFailed;
frame.NavigationStopped += onRootFrameNavigationStopped;
}

private void onRootFrameNavigated(object sender, NavigationEventArgs e)
{
if (_currentVM != null)
{
if (_currentVM is INavigatedViewModel)
{
(_currentVM as INavigatedViewModel).OnNavigatedFrom(e);
}
_currentVM = null;
}

var page = e.Content as PhoneApplicationPage;
if (page != null && page.DataContext is INavigationBase)
{
_currentVM = page.DataContext as INavigationBase;

if (_currentVM is INavigatedViewModel)
{
(_currentVM as INavigatedViewModel).OnNavigatedTo(e);
}
}
}

private void onRootFrameNavigating(object sender, NavigatingCancelEventArgs e)
{
if (_currentVM is INavigatingViewModel)
{
(_currentVM as INavigatingViewModel).OnNavigatingFrom(e);
}
}

这样如果你需要你某个ViewModel接收到页面导航信息,只需将其实现相应的接口即可。例如:

public class PictureVM : ViewModelBase, INavigatedViewModel 
{

public void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{

}

public void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{

}
}

当页面导航发生时,NavigationController会判断当前页面和被导航页面是否需要触发相应的函数。 

问题就这样丑陋的解决了。另外,这样VM中相应事件的触发会先于View里面哦,各位看官注意了~

posted @ 2011-12-03 19:42 akita 阅读(150) 评论(0) 编辑

前些天看到某些网站不支持Live Writer,某些产品经理还以此为傲,并且觉得这是个了不起的事情。
这个事情不过多评论简短说一句,某些产品经理简直就是脑抽,你们的专业知识不是为了糊弄你,也不是让你糊弄人。
如果一个很简单的事情一定要用什么什么理论,什么什么现象来解释,我只能说,你的脑子已经被奴役了。
ok进入正题。自定义动画(继承AnimationBase)本次不予讨论哈。
等你看完MSDN的文档或我的说明,你会觉得,只要时间够。你可以创造出你想创造的任何动画。
当然,那个时间够的前提,恩,不知道多少算够就是了。。。

 

一,概述

很多人觉得用blend生成一个动画好像是一件很简单的事情,我觉得那样极其没有技术含量,并且会让思维迅速僵化。
作为一个非专业非资深的无证程序员,我只想建议呢,大家有机会还是从代码出发了解Storyboard的前世今生吧~

基础元素类型:

1,DoubleAnimation:明显就是一个判断Double值,对Double值进行处理的一个动画过程。这是动画的基本构成元素。
2,PointAnimation:这..就是一个点了,我可以用这个做出很多点的move,cool。
3,ColorAnimation:这个明显就是改变颜色,当然这个没有point和double那种流动的feel,无法动画起来,只是一个change。

变换方式:

1,关键帧:UsingKeyFrames,对关键点进行处理,其他的交给后台系统自己解决。你标注出关键的位置,指定处理函数。ok,系统处理剩下的。
2,路径形式:UsingPath,显而易见了,就是你指定一个几何路径。
3,自定义:Base,创建自定义动画,这个有点太高深了,不是太高的要求,系统给的还是都能搞定的,毕竟我们不是专业做动画。

Timeline:

这个东东就这样了,时间线,控制动画播放的时间,指定Duration 或者指定Key的time都能很好掌控。
设置AutoReverse会让他自己返回,也就是回到初始状态,似乎没办法让动画单向的返回。只能播放一个轮回。
设置RepeatBehavior可以指定重复次数,里面有几种type自己摸索吧。

TargetName以及TargetProperty:

顾名思义。

EventTrigger和Begin方法:

实现动态的可掌控的动画触发。可以通过EventTrigger把动画赋值给一个ButtonClick之类的Event;
当然StoryBoard类还具有类似Stop,Pause,Resume之类的方法。
但是注意Stop之后动画对所有属性进行的更改全部会回到动画以前的状态,需要避免落差,请看下文。

FillBehavior:

就像你打开的某个程序正在读写一个文件流,然后你就无法操作那个文件了一样。
StoryBoard在设置FillBehavior为Filling后(动画结束默认自动设置为Filling),你无法对其TargetProperty进行更改,即使是Stop了也不能。
解决办法有三个,我比较喜欢使用第一种方法:

1,声明时调整FillBehavior 为Stop;
2,移除该StoryBoard;
3,代码中重新BeginAnimation,保持原来的TargetProperty,但是将第二个参数Timeline置为null即可释放。

但是有的情况FillBehavior值的设定却不起作用了,详情见下文。

HandOffBehavior:

如果有两个动画,第二个接上第一个直接播放,第一个动画未触发停止事件,这时会考虑到HandOffBehavior为SnapshotAndReplace 的情况。
第一个的FillBehavior的设置失效,也就是说,即使你想要那个你设置第一个SB的FillBehavior为Stop,想要你的的Property回到开始状态,不被第一个动画更改,他都回不去了。而第二个动画会直接在第一个动画后进行效果的叠加,初始值变成了第一个动画末尾的状态。解决办法让第一个动画停止之后,再执行第二个动画。
另外,该值可以被置为Compose,也就是Append模式。我的理解是在第一个动画完成后再播放第二个,并未测试。

垃圾回收:

动画一定要记住垃圾回收,不然他会一直占用时钟资源。至少离开页面请停止动画的播放。不然就得等到那个页面被回收。

 

二,动画类型入门

From/To/By

很好,我们再来顾名思义一下。这个是可以应用在很多种类动画中的一个方式,很常见。可以作为Attribute设置在某个Animation的Xaml里面,也可以代码指定。
属性名称 <*Animation> *为操作元素,可以操作的元素也相当之多。MSDN有一张大表如下:

 

 

 

1,From也就是起始值,指定这个动画的起始值。一般要搭配To,只指定该值,他会默认以该属性基值为To的目标。
2,To也就是终止值,如果不搭配From。则直接由当前点作为起始值,而运行到To的目标值。
3,By相对位移。相对于开始值的位移,指定From时初始值为From的值,未指定From值时,初始值为当前状态值。

KeyFrameAnimation

下面来到关键帧动画,不同于FTB动画。关键帧重点在于设置关键帧的参数。其他的交给系统处理。和FTB一样支持很多元素,离散,线性,样条插值看各自情况。
属性名称是 <*AnimationUsingKeyFrames> 操作元素见上表。

1,插值方式:离散插值动画为跳变形式,线性则是缓慢,而样条则采用贝赛尔曲线,指定控制点值进行动画处理。
2,TimeSpan:timespan有很多形式,Uniform 和百分比可以让你的动画动态赔时间,而不是简单的Duration。

PathAnimation

路径动画很有意思,他的输入是一个PathGeoMetry,一个几何的绘图。根据这个几何绘图配合Timeline产生出很棒的动画效果。
属性名称是 <*AnimationUsingPath> 操作元素见一表。这个部分最大的难点可能就在于几何图像的绘制了,其他部分大同小异。

EasingFunction

各种各样的缓动函数大家在blend里面观摩设置即可,我就不说这块了。

三,Tips

这部分是我个人看了MSDN动画说明部分,针对自己的一些小贴士了;

1,动画的触发可以用DataTrigger数据改变触发,Trigger属性改变触发,EventTrigger事件触发等。
2,颜色也是可以线性改变的。用线性的LinearColorAnimation即可
3,Freezable对象可以注册后动画,或者间接访问。
4,动画的AccelerationRatio和DecelerationRatio属性可以对动画播放进行加减速处理。
5,动画的IsCumulative属性可以设置重复过程中是否累加值。
6,动画的IsAdditive属性可以让From To动画变成ToTo动画哈哈,就是将From设置为当前值的偏移值作为起点。
7,Button指定Trigger还能直接对SB进行播放暂停停止等动作。
8,如果一个对象包含多个动画,可以使用子时间线添加到SB中便于逻辑和测试。
9,时钟变化是有触发的,不过没特别的需求时不需要对时间变化进行维护。
10,要做严谨的动画很难,但是要做一个能看得过去的动画很简单。到此吧。

四,相关链接

http://msdn.microsoft.com/zh-cn/library/ms752312.aspx

http://msdn.microsoft.com/zh-cn/magazine/cc189019(VS.95).aspx

posted @ 2011-08-07 17:03 akita 阅读(111) 评论(0) 编辑

今天研习WP多语言的实现过程,Culture类就不多介绍了。说明很详细,可以获取当前Culture 和当前UICulture。

第一档,关于Tile 和 StartMenu 中程序名称的现实:

1.首先是用Win32 建立Project:AppResLib,一个空的DLL项目。
2.设置属性-链接-高级-无入口点
3.然后添加资源文件 String Table。
4.编译后添加 .xxxx.mui

第二档,UserControl等控件中添加 Language 属性。

第三档,程序资源多语言

1.首先添加默认资源项。
2.添加 .xx-XX.resx 资源项。
3.在 Property – Assembly 中设置 Neutral Language。
4.更改 .csproj 文件,修改类似: <SupportedCultures>de-DE;es-ES;</SupportedCultures>。
5.更改每个资源项目的 AccessModifier 为 Public。
6.自己建立一个资源的处理类

private static Resources.LangResource localizedResources = new Resources.LangResource();
public Resources.LangResource LocalizedResources
{
    get
    {
        return localizedResources;
    }
}

7.在App.xaml中添加资源

<local:LocalizedStrings xmlns:local ="clr-namespace:YOURAPP" x:Key="LocalizedStrings" />

8.在xaml中显示的字符串全部替换为下方命令(resourceName是字符串的名字)

"{Binding Path=resourceFile.resourceName, Source={StaticResource LocalizedStrings}}"

posted @ 2011-07-25 19:49 akita 阅读(170) 评论(0) 编辑

芒果推出了本地数据库之后,要求运用 Linq to SQL 进行数据控制。

数据库和界面逻辑对应起来的实现形式是这样的:

1,用数据库逻辑和标记直接建立 Model,一般继承自INotifyPropertyChanged, INotifyPropertyChanging;

2,和 DataContext 对应起来,继承DataContet 建立子类,在类中进行数据库的链接,定义Table集合。这个类是数据库和程序主体的桥梁;

3,在 ViewModel 中新建自己建立的DataContext 子类的对象,并且通过Linq 将其和ObservableCollection 进行对接;

4,在 View 中绑定。

Tips:

1,在CheckBox,TextBox这类控件进行了双向绑定后,手动更改界面值不仅仅会造成起ViewModel 中的ObservableCollection 发生改变,甚至可以直接影响到 DataContext 链接的数据库;

2,数据库更改后注意各种提交,InsertOnSubmit(),DeleteOnSubmit(),保存数据库用SubmitChanges();

3,可以使用DatabaseSchemaUpdater 可用来更新数据库的结构,自身结构等级,添加列等,调用 DatabaseSchemaUpdater.Execute() 执行更新;

4,数据库的Connection Strings 链接参数,在DataContext 构造函数中选择,形式为:DataContext(string connectionStrings);

Parameter

Description

data source ordatasource

The file path and name of the local database file. When this is the only connection string property specified, only the value of the property is required to instantiate a data context object. For more information about a data context, seeLocal Database Overview for Windows Phone.

Use the following prefixes to explicitly specify the root location of the path:

  • isostore: path is applied to isolated storage

  • appdata: path is applied to the installation folder

When a prefix is not specified, the file path is applied to isolated storage.

Password or Pwd ordatabase password orssce:database password

The database password, which can be up to 40 characters in length. If not specified, the default value is no password. This property is required if you enable encryption on the database. If you specify a password, encryption is automatically enabled on the database. If you specify a blank password, the database will not be encrypted.

NoteNote:
You cannot encrypt a database after it has been created.

max buffer size orssce:max buffer size

The largest amount of memory, in kilobytes, that a local database can use before it starts flushing changes to disk. If not specified, the default value is 384. The maximum value is 5120.

max database size orssce:max database size

The maximum size of a local database, in megabytes. If not specified, the default value is 32. The maximum value is512.

Mode or file mode orssce:mode

The mode to use when opening the database file. The following values are valid:

  • Read Write: Allows multiple processes to open and modify the database. This is the default setting if the mode property is not specified.

  • Read Only: Allows you to open a read-only copy of the database.

  • Exclusive: Does not allow other processes from opening or modifying the database.

  • Shared Read: Allows other processes to read, but not modify, the database while you have it open.

Culture Identifier

The culture code to use with the database. For example, en-US for United States English. For the full list of supported culture codes in Windows Phone OS 7.1, see Culture and Language Support for Windows Phone.

NoteNote:
This property is ignored if used when connecting to an existing database.

Case Sensitive orCaseSensitive

A Boolean value that determines whether or not the database collation is case-sensitive. Must be set to true to enable case-sensitive collation or false for case-insensitive collation. If not specified, the default value is false.

NoteNote:
This property is ignored if used when connecting to an existing database.
Important note Important Note:

Some Microsoft SQL Compact connection string parameters may work in this release of the Windows Phone Application Platform. We do not recommend using any connection string parameters that are not listed in this topic.

5,可以用 [Association] 标签关联两个数据库,下面摘自MSDN 关于数据库属性标签的说明:

Attribute

Example

Description

TableAttribute

[Table]

Designates a class as an entity class that is associated with a database table.

ColumnAttribute

[Column(IsPrimaryKey = true)]

Associates a class with a column in a database table. IsPrimaryKeyspecifies the primary key, for which an index is created by default.

IndexAttribute

[Index(Columns="Column1,Column2", IsUnique=true, Name="MultiColumnIndex")]

Written at the table level, designates additional indexes on the table. Each index can cover one or more columns.

AssociationAttribute

[Association(Storage="ThisEntityRefName", ThisKey="ThisEntityID", OtherKey="TargetEntityID")]

Designates a property to represent an association, such as a foreign key to primary key association.

posted @ 2011-07-20 11:23 akita 阅读(183) 评论(0) 编辑
摘要: 前些天发过一个LinkLabel的文章,这些天我用过之后发现很多不方便的地方,前两天着手改进了一下。 给link类添加一个属性叫type,目的是为了给不同类型例如 @xxx #xxx# 和 http:// 甚至是邮箱和电话号码的 Hyperlink button 添加了一个分类的处理方式,这样好像有点繁琐,不过似乎是一个最简单易于实现的办法了。 第一步:扫描发现所有Link 类型,为每一个link...阅读全文
posted @ 2011-06-21 20:58 akita 阅读(29) 评论(0) 编辑
摘要: 很早就关注了这个项目但是当时似乎没什么太大诱人之处,也算一种hack最近看到一个截图软件:http://forum.xda-developers.com/showthread.php?t=1093169所以又开始关注起来。。。:http://forum.xda-developers.com/showthread.php?t=1006331先到这,有需求的可以自己上去瞄两眼,详细资料上边链接很全了。我还没研究完呢。。。阅读全文
posted @ 2011-06-01 16:43 akita 阅读(53) 评论(0) 编辑
摘要: 旧的征程尚未结束,新的旅程已经开始,Mango让我很是欣慰啊。国外的一篇小结,照搬~ Top level features: Background processing New profiler and emulator for testing Use of Silverlight + XNA together Silverlight 4 IE9 web browser control Live ...阅读全文
posted @ 2011-05-25 00:59 akita 阅读(69) 评论(0) 编辑
摘要: 以前一直用 BasicAuth 作验证,不过 Sina 声明从六月份开始正式停止对 BasicAuth 的支持,因为保密性能太差,的确,谁也不希望自己的用户名和密码一直在天上飘来飘去,被拦截已经不是时间问题,而是必然的了。 然而 Oauth 对我们这种小型爱好者有一个问题就是需要到网页端去点击那个确认授权,可是我们是可以让用户在软件内输入用户名密码的。虽然这样还是会让我(也就是第三方软件提供方)直...阅读全文
posted @ 2011-05-24 17:28 akita 阅读(801) 评论(13) 编辑