You are browsing the archive for BaseBehavior.

Hidden Object: Episode 7 – Use an Action to Toggle the Magnifier Behavior

September 26, 2009 in Hidden Object Game, Silverlight

This is episode 7 of Creating a Hidden Object Game is Silverlight 3.

In the last few posts we have been working on the magnifier feature of the game which we will finish in this episode.

Please review the following posts:

First we will add in the following files into the ClutteredCube project:

The first thing we want to do is to change MagnifierOverBehavior so that it inherits from our custom behavior base class thus inheriting the IsEnabled property:

public class MagnifierOverBehavior : BaseBehavior<FrameworkElement>

The only other change we need to make this behavior is not set the Effect property on MouseEnter but instead in MouseMove based on the value of the IsEnabled property:

private void AssociatedObject_MouseEnter( object sender, MouseEventArgs e )
{
  this.AssociatedObject.MouseMove += new MouseEventHandler( AssociatedObject_MouseMove );
  //this.AssociatedObject.Effect = this.magnifier;
}

private void AssociatedObject_MouseMove( object sender, MouseEventArgs e )
{
  if (IsEnabled)
  {
    if (this.AssociatedObject.Effect != this.magnifier)
    {
      this.AssociatedObject.Effect = this.magnifier;
    }
    ...
  }
}

In Blend, open the MainPage and select the MagnifierOverBehavior in the Object tree under magnifierCanvas. Name the behavior magnifierBehavior and set IsEnabled to false:

From the Assets tab drag two instances of SetInteractionPropertyAction onto the CheckBox magnifier control:

On the first one, set the properties as follows:

  • EventName: Checked
  • TargetName: magnifierCanvas
  • ObjectName: magnifierBehavior
  • PropertyName: IsEnabled
  • Value: true

Set the second the same as the first, except:

  • EventName: Unchecked
  • Value: false

Make sure that the CheckBox control IsChecked property is false to match the InEnabled value of false for magniferBehavior.

Run the game and verify that magnification is only turned on when the CheckBox is checked.

Let’s do one more thing to finish this episode. Notice that magnifier.png has a white background behind the glass part of the magnifying glass. The image should be on top of something white like a notepad. Import the notepad image and drop it at the bottom of LayoutRoot.

notepad

Position it how you want it and move the magnifier CheckBox on top of it.

Source Code

Demo

There are many features to add so I will keep the next episode contents a surprise.

Base Classes for Custom Behaviors

September 21, 2009 in Silverlight

Behaviors are a powerful way to encapsulate functionality and make it available for designers to use in Blend 3. As your library of custom behaviors grows, you might notice a number of properties that most of your behaviors use. You know that duplication of each of these properties in each of your behaviors is not the right way to go, so you want to create a base class that all your custom behaviors use.

The TriggerAction base class includes an IsEnabled property which I would like to include in all my custom behaviors. Instead of adding the DependencyProperty and associated code to each custom behavior, let’s create a base behavior class.

The existing behavior base classes are:

If we create a custom behavior, MyBehavior, that inherits from Behavior<DependencyObject> and in Blend 3 drop the behavior on the LayoutRoot Grid, we get a behavior with no properties defined:

 

 

To create a base class for our custom behaviors, create an abstract BaseBehavior class that inherits from Behavior<T>. This is where we add the IsEnabled property and any other common properties we want our custom behaviors to have. Next derive a BaseBehavior<T> class from BaseBehavior. It is from BaseBehavior<T> that we will derive our custom behaviors:

 

092209_0022_BaseClasses4.png

The code for BaseBehavior simply derives from Behavior<T> and defines the property, dependency property, and callback method for the IsEnabled property:

 

public abstract class BaseBehavior : Behavior<DependencyObject>
{
    internal BaseBehavior()
    {
    }

    #region IsEnabled (Dependency Property)

    [Category("Common Properties")]
    public bool IsEnabled
    {
        get
        {            
            return (bool)base.GetValue(IsEnabledProperty);
        }
        set
        {
            base.SetValue(IsEnabledProperty, value);
        }
    }

    public static readonly DependencyProperty IsEnabledProperty =
        DependencyProperty.Register(
            "IsEnabled",
            typeof(bool),
            typeof(BaseBehavior),
            new PropertyMetadata(true, new PropertyChangedCallback(OnIsEnabledChanged)));

    private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((BaseBehavior)d).OnIsEnabledChanged(e);
    }

    protected virtual void OnIsEnabledChanged(DependencyPropertyChangedEventArgs e)
    {
    }
    #endregion
}

The BaseBehavior<T> class derives from BaseBehavior and redefines the AssociatedObject property using the new keyword. We do this so that the AssociatedObject can be typed when we derive our custom behavior from it:

 
public abstract class BaseBehavior<T>
    : BaseBehavior where T : DependencyObject
{
    protected BaseBehavior() : base() {}

    protected new T AssociatedObject
    {
        get
        {
            return (T)base.AssociatedObject;
        }
    }
}

In MyBehavior, change the class definition from:

 
public class MyBehavior : Behavior<DependencyObject>

to

public class MyBehavior : BaseBehavior<DependencyObject>

BaseBehavior<T> is a drop-in replacement for Behavior<T>. When we recompile and view the behavior’s properties in Blend, we see that the IsEnabled property has been added:

 

  

As needed, we can add additional properties to BaseBehavior.

What other properties do you think should be added to BaseBehavior?

Source code