UWP开发:自定义Behavior的使用

Cle****-he UID.1073626
2015-10-27 发表

这是我第三次探索Behavior,依然记得2年前第一次和Behavior打交道。

郑州,2013年初……

当时刚毕业不久,满腔热血的投入到WindowsPhone App 开发,一个毛头小子对什么都充满了好奇,对WindowsPhone的开发工具自然而然的也一一进行探索,其中Blend肯定是少不了去接触的。然而一次无意的探索让我第一次接触到Behavior。

当时对Behavior的概念几乎没有,百度一番过后得知是拖放到控件上就能产生一定的行为效果,于是就把Blend中提供的所有Behavior挨个拖放到控件中看看到底是起什么作用。具体的细节现在都忘记了,只记住了一个特别的Behavior,叫什么也忘记了,记得它的作用是能让控件支持随意拖动的行为,也就是可以用手指将一个小球(Ellipse控件)随意放置到屏幕任何位置。那时的我兴奋的好像自己实现了什么多牛逼的功能似的,其实然并卵而已,兴奋了几天后也就忘记了Behavior的存在。这就是我第一次和Behavior打交道,懵懂而又青涩……

第二次和Behavior打交道是因为MVVM框架,使用Blend 提供的Behavior能够很方便的使UI与VM逻辑结合起来,使得代码很清爽干净,但也仅仅局限于使用Blend中提供的Behavior,具体的Blend 中内置的Behavior使用方法请移步:Behavior的使用详解

最近在开发中,接触到了自定义Behavior,百度谷歌一番,无不发现每个开发者对Behavior的赞美。那么Behavior到底是什么?真的那么神奇?

简单点说就是,Behavior可以让某些功能行为附加到一个控件上,也就是说Behavior可以定义一组行为来循环使用或者提供给其他人使用。

那么自定义Behavior在UWP中到底怎么使用?下面我们就来利用自定义Behavior实现一个行为(Blend中自带的Behavior在这里不讨论)。

例子:自定义一个Behavior,实现元素鼠标经过时变大、离开时变小。

首先添加Behaviors SDK引用(忽略兼容性提示),实现自定义Behavior必须继承Behaviors SDK 中的DependencyObject 类并实现IBehavior接口。
***附件停止解析***


新建一个类,暂时起名叫做BtnGetFocusBehavior.cs ,继承DependencyObject 类并实现IBehavior接口
[mw_shl_code=csharp,true]public sealed class BtnGetFocusBehavior : DependencyObject, IBehavior
{
public void Attach(DependencyObject associatedObject)
{
throw new NotImplementedException();
}

public void Detach()
{
throw new NotImplementedException();
}

public DependencyObject AssociatedObject { get; }
}[/mw_shl_code]



代码中Attach方法就是当该Behavior被关联到某一元素时要执行的代码,参数为元素对象的引用

Detach方法是党Behavior与关联的元素分离时要执行的代码

AssociatedObject是获取与Behavior关联起来的元素对象



接下来我们需要在Attach方法中实现被关联元素所拥有的行为,代码很简单就不解释了
[mw_shl_code=csharp,true]public sealed class BtnGetFocusBehavior : DependencyObject, IBehavior
{
private DependencyObject _associatedObject;

private readonly Storyboard _focuStoryboard = new Storyboard();

private const double AnimFrom = 1;

private const double AnimTo = 1.5;

private readonly DoubleAnimation _scaleXAnim = new DoubleAnimation();

private readonly DoubleAnimation _scaleYAnim = new DoubleAnimation();

public void Attach(DependencyObject associatedObject)
{
//获取关联的对象
_associatedObject = associatedObject;
if (associatedObject == null) return;
var obj = _associatedObject as FrameworkElement;
if (obj == null) return;

var ct = new CompositeTransform();
//添加CompositeTransform缩放支持
obj.RenderTransform = ct;

//设置动画关联对象
Storyboard.SetTarget(_scaleXAnim, obj.RenderTransform);
Storyboard.SetTargetProperty(_scaleXAnim, nameof(CompositeTransform.ScaleX));

//设置动画关联对象
Storyboard.SetTarget(_scaleYAnim, obj.RenderTransform);
Storyboard.SetTargetProperty(_scaleYAnim, nameof(CompositeTransform.ScaleY));

//将动画添加到故事版
_focuStoryboard.Children.Add(_scaleYAnim);
_focuStoryboard.Children.Add(_scaleXAnim);

//关联事件
obj.PointerEntered += Obj_PointerEntered;
obj.PointerExited += Obj_PointerExited;
}

private void Obj_PointerExited(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
StartScaleStoryboard(AnimTo, AnimFrom);
}

private void Obj_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
StartScaleStoryboard(AnimFrom, AnimTo);
}

private void StartScaleStoryboard(double from, double to)
{
_scaleYAnim.From = _scaleXAnim.From = from;
_scaleYAnim.To = _scaleXAnim.To = to;
_scaleYAnim.EasingFunction = _scaleXAnim.EasingFunction = new ExponentialEase { Exponent = 4 };
_scaleYAnim.Duration = _scaleXAnim.Duration = new Duration(TimeSpan.FromSeconds(0.3));
_focuStoryboard.Begin();
}

public void Detach()
{
var obj = _associatedObject as FrameworkElement;
if (obj==null) return;
//解除事件
obj.PointerEntered -= Obj_PointerEntered;
obj.PointerExited -= Obj_PointerExited;
}

public DependencyObject AssociatedObject => _associatedObject;
}[/mw_shl_code]



实现了自定义Behavior后,来看看在UI上怎么使用。

首先引用Microsoft.Xaml.Interactivity命名空间,我们需要把我们的Behavior放入到Interaction.Behaviors里面,这样才能使Behavior关联到我们的元素中,如下:
[mw_shl_code=csharp,true]xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Ellipse Width="100" Height="100" Fill="#FF1E5FBD" RenderTransformOrigin="0.5,0.5" >
<Interactivity:Interaction.Behaviors>
<beh:BtnGetFocusBehavior />
</Interactivity:Interaction.Behaviors>
</Ellipse>
</Grid>[/mw_shl_code]


其实还有个更方便的使用我们自定义的Behavior的方法

我们打开Blend – "资产"面板 – "Behaviors行为",看看里面有什么?
***附件停止解析***


对,有我们刚自定义的BtnGetFocusBehavior,在Blend中我们可以直接拖拽该Behavior到页面的任意元素上,界面代码Blend会自动帮我们实现,是不是很方便?

Ok,Demo很简单,但意义重大,起个抛砖引玉功能,更优秀的Behavior还需要大家花花心思好好设计一番。

来看下运行效果:
***附件停止解析***


本文出自:53078485群大咖Aran

敬告:
为防止不可控的内容风险,本站已关闭新用户注册,新贴的发表及评论;
你现在看到的内容只是互联网用户曾经发表的言论快照,仅用于老用户留存纪念,且仅与科技行业相关,全部内容不代表本站观点及立场;
本站重新开放前已针对包括用户隐私、版权保护、信息安全、国家政策在内的各种互联网法律法规要求,执行了隐患内容的自查、屏蔽和删除;
本站目前所属个人主体,未有任何盈利安排与计划,且与原WFUN.COM所属公司不存在任何关联关系;
如果本帖内容或者相关资源侵犯到您的合法权益,或者您认为存在问题,那么请您务必点此举报或投诉!
全部回复:
前面的路 UID.932351
2015-10-27 使用 Lumia 920T 回复

谢谢分享

ilakb24 UID.707208
2015-10-27 回复

高大上的样子,酷酷的

tmp00000 UID.995403
2015-10-27 回复

好文章,顶一次

qiqiminmin UID.638527
2015-10-27 回复

本帖最后由 qiqiminmin 于 2015-10-28 22:37 编辑

楼主的不错,但是用过winjs开发,在UI上会有更大优势,也更简洁,以下就可以实现很多UI



[mw_shl_code=css,true]cycle
{
width: 200px;
height:200px;
border-radius: 100px;
background-color:blue;
}

cycle:hover
{
transform:scale(1.5,1.5);
}[/mw_shl_code]

***附件停止解析***

vbfool UID.352791
2015-10-28 回复

Behavior又不是只有这点功能,人家是一种模式,用来封装代码段而已。
放大那是个动画,本来也是推荐用样式的,Behavior更适合做的不一定是这些。

用过Blend的可以看看这个,这个也是不需要几句话的,因为微软帮你把一些东西封装好了。
***链接停止解析***

qiqiminmin UID.638527
2015-10-28 回复

本帖最后由 qiqiminmin 于 2015-10-28 22:29 编辑

Quote***链接停止解析***
Behavior又不是只有这点功能,人家是一种模式,用来封装代码段而已。
放大那是个动画,本来也是推荐用样式 ...


我都不好意思给你解释html5的其他动画了,我说的是Xaml在UI上的弊端就是繁琐,即使封装一个动画都这么麻烦。

vbfool UID.352791
2015-10-28 回复

Quote***链接停止解析***
我都不好意思给你解释html5的其他动画了,我说的是Xaml在UI上的弊端就是繁琐,即使封装一个动画都这么麻 ...


问题是没什么人拿他来“封装动画”
这东西更类似于jquery、bootstrap之类的常用的属性,比如我写个Behavior用来关闭当前的窗体/应用,用的话直接附加到某个控件上就行了,难道你用CSS直接就能实现这个功能?我写个TriggerAction,附加到按钮上,用来实现点一下弹出一个对话框,你用CSS实现这个?你难道不是要用js写个函数实现功能,然后挂上CSS选择器,然后再在HTML的元素上加上class?或者直接加个属性xxx=xxx?

楼主这帖子例子举的很**,然后你用另一个**的方式去证明这个例子很**,这就能用来证明这个功能本身很**?

qiqiminmin UID.638527
2015-10-28 回复

本帖最后由 qiqiminmin 于 2015-10-28 22:42 编辑

Quote***链接停止解析***
问题是没什么人拿他来“封装动画”
这东西更类似于jquery、bootstrap之类的常用的属性,比如我写个Behavi ...


我强调的是UI,如果你不懂什么是UI,自己查查也行。

点击一个按钮,弹出窗口,你就按你的理解好了。

你举例子是2011年的,随便就联系到wpf,silverlight,( ̄▽ ̄)",我只能笑笑了,您以后多举举uwp例子吧,没有其他要求。

也许我说的不太好听,但是是自己的实话,在xaml多一份心思,就是多浪费一份宝贵的时间,多往前看。 我都没有建议让人不开发uwp程序,已经够客气了。从趋势来看,xaml被淘汰时迟早的事。

vbfool UID.352791
2015-10-28 回复

Quote***链接停止解析***
我强调的是UI,如果你不懂什么是UI,自己查查也行。

点击一个按钮,弹出窗口,你就按你的理解好了。


兄弟,丑不丑,在于实现度,直接让程序员负责界面,然后说人家丑,你的UI人员干嘛去了呢?

正好你上次说的那个肌肉图我挺好奇的,能发出来一下你得数据文件么?我好写个例子看看。

qiqiminmin UID.638527
2015-10-28 回复

本帖最后由 qiqiminmin 于 2015-10-29 03:44 编辑

Quote***链接停止解析***
兄弟,丑不丑,在于实现度,直接让程序员负责界面,然后说人家丑,你的UI人员干嘛去了呢?

正好你上次说 ...


我在国内以前开发wpf五年,硬生生把我培养成了一个比普通水平UI水平要高的美工。为什么我吐槽,因为深受其害。

肌肉图,我自己用AI描出来的,生成svg。( ̄▽ ̄)"。可以给你部分玩玩。Xaml上也可以体现出的,但是我觉得那没啥意义。Xaml如果自己懂矢量图显示就没啥问题.

vbfool UID.352791
2015-10-28 回复

Quote***链接停止解析***
我在国内以前开发wpf五年,硬生生把我培养成了一个比普通水平UI水平要高的美工。

肌肉图,我自己用AI描 ...


对你没意义,对我也许有意义,对别人也许也有意义。
我到现在PS是只会切图的水平,都是靠实现效果图的能力。
我们公司的美工,现在Blend也用的挺溜的,虽然有些时候还是要帮他改。

而且我敢打赌,如果你不是一个“比普通水平UI的水平高的美工”,你拿了HTML5+CSS3,一样什么都做不出来。

qiqiminmin UID.638527
2015-10-28 回复

本帖最后由 qiqiminmin 于 2015-10-29 03:42 编辑

Quote***链接停止解析***
对你没意义,对我也许有意义,对别人也许也有意义。
我到现在PS是只会切图的水平,都是靠实现效果图的能 ...



***附件停止解析***


( ̄▽ ̄)",也许。。。。 不过我自己也知道 html5+css得益于 ionic,比之前用xaml要好太多,我感觉容易多了,也许我感觉是错误的。附件以上有几块肌肉的数据图,本想以代码形式展现,说我字数太多,只能做附件了,您感兴趣自己玩玩吧。这没什么好保留的,很简单的。

都可以给您看看html程序部分,我很乐意介绍新的方法。这里很多东西,其实都是我以前梦寐以求的东西,所以当我发现可以这样写,真的太好了。画好svg图,在html里加上以下代码,全部搞定。

在ios和安卓上,有很多软件,就是教孩子画画,然后给一块一块上色,因为ios和安卓,一个是本身就支持svg,还有很多就是用html5开发。微软也有,但是我估计很多公司不会愿意花精力自己再弄个东西来弄。

[mw_shl_code=html,true]
<svg id='bodySvg' class="body-chart" style='padding: 10px; ; max-height: 400px; width: 100%; display: inline-block ' viewBox="0 0 507 392" data-reactid=".0">
<g class='muscleClass {{muscle.name}}Class' ng-repeat="muscle in muscles" data-muscle="{{muscle.name}}" ng-click="musleClick(muscle)" fill="{{muscle.file}}" stroke="#010101" data-reactid=".0.0">
<use data-muscle="{{muscle.name}}" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="{{'body.svg#' + muscle.name}}"></use>
</g>
</svg>
[/mw_shl_code]

本站使用Golang构建,点击此处申请开源鄂ICP备18029942号-4联系站长投诉/举报