views:

148

answers:

1

I'm trying to determine if Attached Behaviors are something we need in building controls for the forms in our application.

Hence, I not only want to know how to create Attached Behaviors but want to see real instances in which they are used to solve problems. I used this MSDN article to create a UserControl with an attached property in a way that I think would be useful, namely, a stackpanel in which certain child elements are either highlighted or not highlighted.

This example runs fine, but where do I put the logic to highlight or not highlight (e.g. change the background color) of the child elements?

XAML:

<Window x:Class="TestAttachedProperties2343.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestAttachedProperties2343"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <local:ExtendedStackPanel>
            <TextBlock local:ExtendedStackPanel.IsHighlighted="True" Text="text1"/>
            <TextBox local:ExtendedStackPanel.IsHighlighted="False" Text="text2"/>
            <TextBox local:ExtendedStackPanel.IsHighlighted="True" Text="text3"/>
        </local:ExtendedStackPanel>
    </Grid>
</Window>

Code Behind:

using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System;

namespace TestAttachedProperties2343
{
    public partial class ExtendedStackPanel : StackPanel
    {
        public static readonly DependencyProperty IsHighlightedProperty = DependencyProperty.RegisterAttached(
            "IsHighlighted",
            typeof(Boolean),
            typeof(ExtendedStackPanel),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));

        public static void SetIsHighlighted(UIElement element, Boolean value)
        {
            element.SetValue(IsHighlightedProperty, value);
        }
        public static Boolean GetIsHighlighted(UIElement element)
        {
            return (Boolean)element.GetValue(IsHighlightedProperty);
        }

        public ExtendedStackPanel()
        {
            InitializeComponent();
        }
    }
}
+1  A: 

Here is a real altough very simple example: an attached behavior that shows a message when a user clicks a button. The message can be customized via a dependency property in the behavior itself.

The behavior code:

public class MyBehavior : Behavior<Button>
{
    public static readonly DependencyProperty MessageProperty =
        DependencyProperty.Register("Message",
        typeof(string), typeof(MyBehavior),
        new PropertyMetadata("Default message"));

    public MyBehavior()
        : base()
    { }

    public string Message
    {
        get { return (string)GetValue(MessageProperty); }
        set { SetValue(MessageProperty, value); }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Click += new RoutedEventHandler(AssociatedObject_Click);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.Click -= new RoutedEventHandler(AssociatedObject_Click);
    }

    void AssociatedObject_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(Message);
    }
}

The XAML that uses the behavior:

<Button x:Name="MyButton" Content="Click me for custom behavior">
    <i:Interaction.Behaviors>
        <local:MyBehavior Message="Hello from custom behavior"/>
    </i:Interaction.Behaviors>
</Button>

They key here is that you must override the OnAttached and OnDetached methods. Here you attach/detach handlers to whatever events you want to control in the associated element, and do whatever you want in the handlers. It is a very powerful and flexible way for adding interactivity to visual controls.

Update

The base Behavior<> class is in the System.Windows.Interactivity.dll assembly which is not part of the Silverligh runtime, but is installed with Microsoft Expression Blend 3. It seems anyway that this assembly can be freely redistributed (see here: http://social.expression.microsoft.com/Forums/en-US/blend/thread/8523aec4-1a10-4864-8ad4-f95a3627bb4a)

Konamiman
What do I need to reference to use the "Behavior" class, I find only System.ComponentModel.CategoryAttribute.Behavior (http://msdn.microsoft.com/en-us/library/system.componentmodel.categoryattribute.behavior.aspx) in System.dll, which I have referenced by it says type "Behavior" cannot be found.
Edward Tanguay
You need to reference the System.Windows.Interactivity assembly. It is installed as part of Expression Blend 3.
Konamiman
This works well in WPF and I technically understand how it works. I am think how we could use this in our forms, perhaps to instead of a message define an ItemType (Customer or Employee) and therefore have different validations, messages, etc. How do you use it in real world applications?
Edward Tanguay