UWP开发:自定义Behavior的使用

来源:互联网 发布:算法导论 豆瓣 编辑:程序博客网 时间:2024/05/19 06:47
这是我第三次探索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接口
public sealed class BtnGetFocusBehavior : DependencyObject, IBehavior{    public void Attach(DependencyObject associatedObject)    {        throw new NotImplementedException();    }     public void Detach()    {        throw new NotImplementedException();    }     public DependencyObject AssociatedObject { get; }}



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

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

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

 

接下来我们需要在Attach方法中实现被关联元素所拥有的行为,代码很简单就不解释了
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;   }



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

首先引用Microsoft.Xaml.Interactivity命名空间,我们需要把我们的Behavior放入到Interaction.Behaviors里面,这样才能使Behavior关联到我们的元素中,如下:
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>




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

我们打开Blend – "资产"面板 – "Behaviors行为",看看里面有什么?


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

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

来看下运行效果:



本文出自:53078485群大咖Aran
0 0