亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Behaviors and Triggers(Foward)

系統 1888 0
1. Introduction

With the release of Silverlight 3, a lot of new cool features have been introduced. One of my favorite definitely is the support of behaviors and triggers. In WPF the triggers are extremely powerful. They allow you to declaratively associate an action with an event or property value. In the previous versions of Silverlight one of the things that were really missing were the triggers and the behaviors. It was not possible, for example, to add mouse-overs to objects declaratively (as in WPF). Currently it is still not possible, you have to write procedural code, but at least that code is separated, so the designer doesn’t have to write it or understand it. In that post I will focus exactly on that new feature in Silverlight and will show you how to create your own custom behaviors and triggers.

2. Prerequisites

In order to write behaviors and triggers you need to have installed the Microsoft Expression Blend SDK on your machine. After that you need to add a reference to the System.Windows.Interactivity.dll assembly which is located in:

{Program Files}\Microsoft SDKs\Expression\Blend 3\Interactivity\Libraries\Silverlight

I don’t know why but this assembly currently is not part of the Silverlight SDK. You can download the Expression Blend product from here .

3. Behavior types

Currently you can use three types of bevahors: Behavour , TriggerAction and TargetedTriggerAction . The class diagram is shown on the next figure:

4. Using the Behavior<T> class

For simple scenarios the generic Behavior<T> class is excellent choice. This class has only two overridable methods which notify the current behavior when an object is attached and detached from it. For my post I will create two behaviors: the first one just inverts the color of an image, when the image is clicked, and the second is little more complicated – it adds an animation and creates a magnifier when the mouse is over the image.

The first thing you should do when creating behaviors is to create a new class which inherits from the generic class Behavior<T> , where T is a dependency object. In the most cases you will inherit from the Behavior<FrameworkElement> or Behavior<UIElement> .

    public class InverseColorClickBehavior : 
  
        Behavior<FrameworkElement>
  
    {
  
        public InverseColorClickBehavior() :
  
            base()
  
        {
  
        }
  
    }
  

For that particular case I am interested in the mouse click event. That’s why in the OnAttached method I will attach to the MouseLeftButtonDown event of the associated with that behavior object. And respectively in the OnDetaching method I will detach from that event.

    protected override void OnAttached()
  
    {
  
        base.OnAttached();
  
        this.AssociatedObject.MouseLeftButtonDown += 
  
            new MouseButtonEventHandler( AssociatedObject_MouseLeftButtonDown );
  
    }
  
    ?
  
    protected override void OnDetaching()
  
    {
  
        base.OnDetaching();
  
        this.AssociatedObject.MouseLeftButtonDown -= 
  
            new MouseButtonEventHandler( AssociatedObject_MouseLeftButtonDown );
  
    }
  

The only thing that's left is to add an inverse color effect to the associated object in the mouse Click event handler.

    private void AssociatedObject_MouseLeftButtonDown( 
  
        object sender, MouseButtonEventArgs e )
  
    {
  
        this.AssociatedObject.Effect = 
  
            this.AssociatedObject.Effect == null ?
  
                this.AssociatedObject.Effect = this.inverseColor :
  
                this.AssociatedObject.Effect = null;
  
    }
  

Once we have created the bahavior we should attach it to a particular object.

    <Image Stretch="Fill"
  
           Source="/Photos/Image1.jpg">
  
        <interactivity:Interaction.Behaviors>
  
            <local:InverseColorClickBehavior/>
  
        </interactivity:Interaction.Behaviors>
  
    </Image>
  

?

My second behavior is little more complicated. It hits more common scenario where you want to add an animation for example on the mouse over event. Again as the first example I will create a new class which inherits from the generic Behavior<T> where T will be a FrameworkElement .

I want when the mouse is over the element to add a magnifier shader effect on the element and when the mouse leaves the element area to remove the effect. That’s why I want to handle the MouseEnter and MouseLeave events in order to enable and disable the effect. On the analogy of the previous case in the OnAttached method I will attach to the MouseEnter and MouseLeave events of the associated with that behavior object. And respectively in the OnDetaching method I will detach from that events. When the mouse is over the element I want to track the mouse move event. That’s why I will attach also to the mouse move event on entering and will detach from it on leaving the element area.

    protected override void OnAttached()
  
    {
  
        base.OnAttached();
  
    ?
  
        this.AssociatedObject.MouseEnter += 
  
            new MouseEventHandler( AssociatedObject_MouseEnter );
  
        this.AssociatedObject.MouseLeave += 
  
            new MouseEventHandler( AssociatedObject_MouseLeave );
  
    }
  
    ?
  
    protected override void OnDetaching()
  
    {
  
        base.OnDetaching();
  
    ?
  
        this.AssociatedObject.MouseEnter -= 
  
            new MouseEventHandler( AssociatedObject_MouseEnter );
  
        this.AssociatedObject.MouseLeave -= 
  
            new MouseEventHandler( AssociatedObject_MouseLeave );
  
    }
  
    ?
  
    private void AssociatedObject_MouseLeave( object sender, MouseEventArgs e )
  
    {
  
        this.AssociatedObject.MouseMove -= 
  
            new MouseEventHandler( AssociatedObject_MouseMove );
  
        this.AssociatedObject.Effect = null;
  
    }
  
    ?
  
    private void AssociatedObject_MouseEnter( object sender, MouseEventArgs e )
  
    {
  
        this.AssociatedObject.MouseMove += 
  
            new MouseEventHandler( AssociatedObject_MouseMove );
  
        this.AssociatedObject.Effect = this.magnifier;
  
    }
  

The whole work is done in the mouse move event handler.

    private void AssociatedObject_MouseMove( object sender, MouseEventArgs e )
  
    {
  
        ( this.AssociatedObject.Effect as Magnifier ).Center =
  
            e.GetPosition( this.AssociatedObject );
  
    ?
  
        Point mousePosition = e.GetPosition( this.AssociatedObject );
  
        mousePosition.X /= this.AssociatedObject.ActualWidth;
  
        mousePosition.Y /= this.AssociatedObject.ActualHeight;
  
        this.magnifier.Center = mousePosition;
  
    ?
  
        Storyboard zoomInStoryboard = new Storyboard();
  
        DoubleAnimation zoomInAnimation = new DoubleAnimation();
  
        zoomInAnimation.To = this.magnifier.Magnification;
  
        zoomInAnimation.Duration = TimeSpan.FromSeconds( 0.5 );
  
        Storyboard.SetTarget( zoomInAnimation, this.AssociatedObject.Effect );
  
        Storyboard.SetTargetProperty( zoomInAnimation, 
  
            new PropertyPath( Magnifier.MagnificationProperty ) );
  
        zoomInAnimation.FillBehavior = FillBehavior.HoldEnd;
  
        zoomInStoryboard.Children.Add( zoomInAnimation );
  
        zoomInStoryboard.Begin();
  
    }
  

To summarize before continuing with the triggers, in my opinion the behaviors is very similar to the extension methods in C#. The only difference is that the behavior is a component. It encapsulates some functionality and can be attached to another component to extend its built-in functionality.

5. Using the TriggerAction<T> class

In simple cases the Behavior<T> class is perfect. The TriggerAction<T> class is useful in much more common cases than the simple Behavior<T> . The TriggerAction<T> offers invoke method which is fired once an event trigger happens. When you use the Behavior<T> class you require that the behavior is responsible for the attaching and detaching of the item events. In comparison when using the TriggerAction<T> you specify which event triggers the action in the XAML, as you will see in the next demo.

I will create a trigger that will apply an animation on the click event. The first step is to create a new class which inherits from the generic TriggerAction<T> class.

    public class WaveTrigger : TriggerAction<FrameworkElement>
  
    {
  
        protected override void Invoke( object parameter )
  
        {
  
            this.waveStoryboard.Begin();
  
        }
  
    }
  

As you can see the Invoke method is the only required method that you need to have in your trigger. But often in the practice you will need to override several other methods of the class. In the constructor of our trigger I need to configure the animation and the storyboard.

    public WaveTrigger() :
  
       base()
  
    {
  
       this.waveAnimation = new DoubleAnimation();
  
       this.waveStoryboard = new Storyboard();
  
       this.waveEffect = new WaveEffect();
  
       this.InitializeTrigger();
  
       this.waveAnimation.AutoReverse = false;
  
       this.waveStoryboard.Children.Add( this.waveAnimation );
  
    }
  
    private void InitializeTrigger()
  
    {
  
        this.waveAnimation.From = -this.WaveFrequency;
  
        this.waveAnimation.To = this.WaveFrequency;
  
        this.waveAnimation.Duration = this.WaveDuration;
  
    }
  

In order to set the animated object as well as the animated property I need to override that the OnAttached method. If you try to do that, for example, in the constructor you won’t succeed due to the fact that the associated object is still unknown.

    protected override void OnAttached()
  
    {
  
        base.OnAttached();
  
  
        this.AssociatedObject.Effect = this.waveEffect;
  
        Storyboard.SetTarget( this.waveAnimation, 
  
            this.AssociatedObject.Effect );
  
        Storyboard.SetTargetProperty( this.waveAnimation, 
  
            new PropertyPath( WaveEffect.WavinessProperty ) );
  
    }
  

The only required method you need to do in the Invoke method is to start the animation.

    protected override void Invoke( object parameter )
  
    {
  
        this.waveStoryboard.Begin();
  
    }
  

In order to make my WaveTrigger configurable I will add several dependency properties (for the duration and for the frequency). This is pretty straightforward. Once we have our trigger the final step is to use it in the XAML.

    <Image Stretch="Fill"
  
           Source="/Photos/Image3.jpg">
  
        <interactivity:Interaction.Triggers>
  
            <interactivity:EventTrigger 
  
                    EventName="MouseLeftButtonUp">
  
                <local:WaveTrigger WaveFrequency="1.9" 
  
                    WaveDuration="00:00:05"/>
  
            </interactivity:EventTrigger>
  
        </interactivity:Interaction.Triggers>
  
    </Image>
  
6. Using the TargetedTriggerAction<T> class

The third type behavior is offered by the generic TargetedTriggerAction<T> class. It represents an action that can be targeted to affect a totally different object rather than its associated object. I can’t remember any practical solution for that type of triggers, but in a few words it allows you to associate the trigger with an object, but to manipulate totally different element. For example in the next demo I will associate a targeted trigger with a button, but the target element (which will be flipped) will be an image.Again as a first step I will create a new class which inherits from the TargetedTriggerAction<T> class.

    public class TurnImageTargetedTrigger : 
  
        TargetedTriggerAction<FrameworkElement>
  
    {
  
        protected override void Invoke( object parameter )
  
        {
  
        }
  
    ?
  
        protected override void OnAttached()
  
        {
  
            base.OnAttached(); 
  
            ( this.AssociatedObject as FrameworkElement ).Loaded += 
  
                new RoutedEventHandler( TurnImageTargetedTrigger_Loaded );
  
        }
  
    ?
  
        protected override void OnDetaching()
  
        {
  
            base.OnDetaching();
  
            ( this.AssociatedObject as FrameworkElement ).Loaded -= 
  
                new RoutedEventHandler( TurnImageTargetedTrigger_Loaded );
  
        }
  
    ?
  
        private void TurnImageTargetedTrigger_Loaded( object sender, RoutedEventArgs e )
  
        {
  
        }
  
    }
  

The trick here is that the target object can be access only when the associated object is loaded. That’s why I need to attach to the Loaded event of the associated object. An Invoke method must also be defined with the only purpose to start the animation. After the trigger is ready we need to use it in the XAML. You can see how this can be done in the next code snippet.

    <Image x:Name="imgToFlip" Stretch="Fill"
  
        Source="/Photos/Image4.jpg"/>
  
    <Button Content="TurnImage">
  
        <interactivity:Interaction.Triggers>
  
            <interactivity:EventTrigger 
  
                    EventName="Click">
  
                <local:TurnImageTargetedTrigger 
  
                    TargetName="imgToFlip"/>
  
            </interactivity:EventTrigger>
  
        </interactivity:Interaction.Triggers>
  
    </Button>
  

And the demo can be seen on the next figure.

7. Behaviors and Expression Blend 3

Once our behavior (trigger) is ready, we can add it directly in XAML or via Expression Blend 3.

Once added to any element the behavior becomes nested inside the object.

The Properties pane you may adjust the behavior (setting properties, which event will fire it, etc.).

If you note in the Assets library except our behaviors created for the current solution there are several other behaviors which are listed in all Expression Blend projects. If you want your own custom behaviors also to be listed for all Blend project you need to register your assembly in the registry. You need to use the following path in the Registry Editor :

HKEY_CURRENT_USER(or HKEY_LOCAL_MACHINE) \Software\Microsoft\Expression\Blend\v3.0\Toolbox\Silverlight\v3.0

8. Using the DefaultTriggerAttribute

By default when you create a new TriggerAction, Expression Blend will associate it with the MouseLeftButtonDown event where it can, or with the Loaded event if the MouseLeftButtonDown is not available. However sometimes you may want a custom Action to be connected with a different default event. In order to do this you should use the DefaultTriggerAttibute:

    public DefaultTriggerAttribute(Type targetType, Type triggerType, 
  
        params object[] parameters)
  

The first parameter is the type for which to create this Trigger, the second is the type of Trigger to create and the final is a list of constructor arguments to the Trigger when it is created. If you specify more than one attribute, the most derived targetType that is applicable when the user create the behavior will be used.

    [DefaultTrigger(typeof(UIElement), typeof(EventTrigger), 
  
        "MouseLeftButtonDown")] 
  
    [DefaultTrigger(typeof(ButtonBase), typeof(EventTrigger), 
  
        "Click")] 
  
    public class WaveAction : TriggerAction<UIElement> 
  
    { 
  
    }
  

If the WaveAction is dragged onto a Button, the Action will be created under a Click EventTrigger. However, if the WaveAction is dragged onto any other UIElement, a MouseLeftButtonDown trigger will be created.

9. Using the TypeConstraintAttribute

You can use the TypeConstraintAttribute to specify type constraints on the AssociatedObject of TargetedTriggerAction and EventTriggerBase .

10. Final words

The motivation for adding behaviors in Silverlight is twofold. First, the behaviors are somehow work-around for the missing triggers in Silverlight. They allow closing the gap between WPF and Silverlight. Second, they allow designers to add interactivity without needing to write any code. I like the behaviors and definitely will use them in any future projects. This post covers quite a bit ground. I hope it was useful for you. In the official site of Expression Blend you can find a lot of ready for use behaviors. Also see the References section for more information.

From: http://www.silverlightshow.net/items/Behaviors-and-Triggers-in-Silverlight-3.aspx

?

?

Last:Event trigger, EventTrigger drived from EventTriggerBase,and EventTriggerBase drived from TriggerBase,TriggerBase drived from ?IAttachedObject

and under EventTrigger, you can define many trigger action,such as:

??????? <Button Content="TurnImage" FontSize="14" FontFamily="{StaticResource PrimaryFontFamily}"
??????????????? Grid.Row="1" Width="100" Margin="0,5,0,0">
??????????? <interactivity:Interaction.Triggers>
??????????????? <interactivity:EventTrigger EventName="Click">
??????????????????? <local:TurnImageTargetedTrigger TargetName="imgToFlip"/>
??????????????????? <local:WaveTrigger WaveFrequency="1.9" WaveDuration="00:00:05"/>
??????????????? </interactivity:EventTrigger>
??????????? </interactivity:Interaction.Triggers>

From the source code:

?

// System.Windows.Interactivity.TriggerBase
/// <summary>
/// Invoke all Actions associated with this trigger.
/// </summary>
/// <remarks>Derived classes should call this to fire the trigger.</remarks>
protected void InvokeActions(object parameter)
{
??? using (IEnumerator<TriggerAction> enumerator = this.Actions.GetEnumerator())
??? {
??????? while (enumerator.MoveNext())
??????? {
??????????? TriggerAction current = enumerator.get_Current();
??????????? current.CallInvoke(parameter);
??????? }
??? }
}

?

?

?

Behaviors and Triggers(Foward)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 五月婷婷视频 | 亚洲综合精品成人啪啪 | 老司机免费福利视频无毒午夜 | 欧美另类69xxxxx视频 | 岛国毛片一级一级特级毛片 | 91www成人久久 | 日本又黄又爽又色的免费视频 | 色婷婷久久久swag精品 | 久久精品国产亚洲网站 | 久久综合久久美利坚合众国 | 国产成人无精品久久久久国语 | 亚洲国产精品yw在线观看 | 久久久久久99 | 456性欧美欧美在线视频 | 亚洲国产乱 | 国产香蕉久久精品综合网 | 毛片大全免费看 | 四虎麻豆| bbw下身丰满18ⅹxxⅹ | 欧美一级夜夜爽 视频 | 99久久国产综合精品女不卡 | 国产三级做爰在线播放最爱 | 九九热精品免费 | 日日噜噜噜夜夜爽爽狠狠图片 | 黄片毛片 | 久久乐国产综合亚洲精品 | 国产精品亚洲精品影院 | 欧美国产精品日韩在线 | 一区二区中文字幕亚洲精品 | 五月婷婷综合激情 | 国产日韩欧美一区 | 五月婷婷亚洲综合 | 欧美特级特黄a大片免费 | 福利在线播放 | 天天干天天干 | 性视频xxx | 欧美国产日韩一区二区三区 | 激情五月五月婷婷 | 一级特级女人18毛片免费视频 | 亚洲综合视频在线观看 | 日本人在线看片 |