<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Silverlight &#124; WPF &#124; Microsoft.Net &#187; Interaction.Behaviors</title>
	<atom:link href="http://joel.neubeck.net/tag/interaction-behaviors/feed/" rel="self" type="application/rss+xml" />
	<link>http://joel.neubeck.net</link>
	<description>Simplifing structure without changing results</description>
	<lastBuildDate>Wed, 26 May 2010 18:43:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Silverlight 3 Drag Behavior</title>
		<link>http://joel.neubeck.net/2009/07/silverlight-3-drag-behavior/</link>
		<comments>http://joel.neubeck.net/2009/07/silverlight-3-drag-behavior/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 17:35:53 +0000</pubDate>
		<dc:creator>joel</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Blend]]></category>
		<category><![CDATA[Interaction.Behaviors]]></category>
		<category><![CDATA[Silverlight 3]]></category>
		<category><![CDATA[System.Windows.Interactivity]]></category>

		<guid isPermaLink="false">http://joel.neubeck.net/?p=406</guid>
		<description><![CDATA[By now most Silverlight developers should have stumbled on a great new feature of Silverlight 3 and Expression Blends, custom Triggers and Behaviors. I seriously don&#8217;t know how I lived without them! In this blog post I am going to demonstrate a simple, yet useful, example of a behavior which allows a UIElement to become [...]]]></description>
			<content:encoded><![CDATA[<p>By now most Silverlight developers should have stumbled on a great new feature of Silverlight 3 and Expression Blends, custom Triggers and Behaviors. I seriously don&#8217;t know how I lived without them!</p>
<p><a href="http://joel.neubeck.net/wp-content/uploads/2009/07/drag_1.PNG"><img class="alignleft size-medium wp-image-410" title="drag_1" src="http://joel.neubeck.net/wp-content/uploads/2009/07/drag_1-300x203.PNG" alt="drag_1" width="300" height="203" /></a>In this blog post I am going to demonstrate a simple, yet useful, example of a behavior which allows a UIElement to become drag able. Figure 1 show the view of my XAML from within Blend. For this example I will create an image with a rounded border which has been placed within a Grid. In the center of my grid I have a Red Rectangle.<br style="clear:both" /><br />
To create my Behavior I will jump in to VS2008 and create a new class that will reside within my solution. If my goal was to create a collection of generic behaviors and triggers I would likely create a Silverlight class assembly and deploy it to the library folder within Blend. This would allow my custom behaviors to be available to all Silverlight or WPF project. The following demonstrates the code I used to create by Drag behavior.</p>

<div class="wp_syntax"><div class="code"><pre class="c-sharp" style="font-family:monospace;">using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Interactivity;
using System.Windows.Media.Imaging;
&nbsp;
namespace DragBehaviors
{
    public class Drag : Behavior
    {
        public static readonly DependencyProperty IsMovableProperty =
            DependencyProperty.Register(&quot;IsMovable&quot;, typeof(bool),
                                        typeof(Drag), new PropertyMetadata(null));
&nbsp;
        [Category(&quot;Target Properties&quot;)]
        public bool IsMovable { get; set; }
&nbsp;
        private bool _isDragging = false;
        private Point _offset;
        private readonly TranslateTransform _elementTranslate = new TranslateTransform();
        private TranslateTransform _imgTranslate = new TranslateTransform();
        private Image _img = new Image();
&nbsp;
        protected override void OnAttached()
        {
            base.OnAttached();
&nbsp;
            AssociatedObject.Loaded += AssociatedObjectLoaded;
            AssociatedObject.HorizontalAlignment = HorizontalAlignment.Left;
            AssociatedObject.VerticalAlignment = VerticalAlignment.Top;
            AssociatedObject.MouseLeftButtonDown += AssociatedObjectMouseLeftButtonDown;
        }
&nbsp;
        void AssociatedObjectLoaded(object sender, RoutedEventArgs e)
        {
            AssociatedObject.RenderTransform = _elementTranslate;
        }
&nbsp;
        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.MouseLeftButtonDown -= AssociatedObjectMouseLeftButtonDown;
        }
&nbsp;
        private void AssociatedObjectMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (!_isDragging) return;
            FrameworkElement parent = _img.Parent as FrameworkElement;
            Point newPosition = e.GetPosition(parent);
&nbsp;
            // Move the dragon via the new position less the offset
            _imgTranslate.X = (newPosition.X - _offset.X);
            _imgTranslate.Y = (newPosition.Y - _offset.Y);
        }
&nbsp;
        private void AssociatedObjectMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (!_isDragging) return;
            Panel panel = AssociatedObject.Parent as Panel;
&nbsp;
            // turn off drag
            _isDragging = false;
&nbsp;
            // Free the Mouse
            _img.ReleaseMouseCapture();
            _img.MouseMove -= AssociatedObjectMouseMove;
            _img.MouseLeftButtonUp -= AssociatedObjectMouseLeftButtonUp;
&nbsp;
            if (IsMovable)
            {
                _elementTranslate.X = _imgTranslate.X;
                _elementTranslate.Y = _imgTranslate.Y;
            }
            _imgTranslate = new TranslateTransform();
            _offset = new Point(0, 0);
            AssociatedObject.Opacity = 1;
            if (panel != null) panel.Children.Remove(_img);
            _img = new Image();
        }
&nbsp;
        private void AssociatedObjectMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            _isDragging = true;
&nbsp;
            AssociatedObject.Opacity = .35;
&nbsp;
            WriteableBitmap bitmap = new WriteableBitmap(AssociatedObject, new TranslateTransform());
            if (_img == null) return;
&nbsp;
            _img.Source = bitmap;
            _img.HorizontalAlignment = HorizontalAlignment.Left;
            _img.VerticalAlignment = VerticalAlignment.Top;
            _img.Stretch = Stretch.None;
            _img.Width = bitmap.PixelWidth;
            _img.Height = bitmap.PixelHeight;
&nbsp;
            _imgTranslate.X = _elementTranslate.X;
            _imgTranslate.Y = _elementTranslate.Y;
&nbsp;
            _img.RenderTransform = _imgTranslate;
            _img.MouseMove += AssociatedObjectMouseMove;
            _img.MouseLeftButtonUp += AssociatedObjectMouseLeftButtonUp;
&nbsp;
            Panel panel = AssociatedObject.Parent as Panel;
&nbsp;
            if (panel != null) panel.Children.Add(_img);
&nbsp;
            _offset = e.GetPosition(_img);
            _img.CaptureMouse();
        }
    }
}</pre></div></div>

<p>For the most part the code should be self explanatory. One cool thing I did was that when I first begin dragging the UIElement, I convert it to a Bitmap and drag an image. The idea is that it will be more efficient to move a image around the screen then the actual collection of UIElements. Once I drop the image than I physically move the UIElement. Note that in its current state this only works correctly if the UIElement I am dragging is Left and Top aligned. This ensures that it is sitting at X=0, Y=0 in the panel it is residing. My guess is that it could be rewritten to support other alignments.</p>
<p>Once the Behavior class is constructed we simply add it to the control we want to drag.</p>

<div class="wp_syntax"><div class="code"><pre class="c-sharp" style="font-family:monospace;">&lt;Border BorderThickness=&quot;1&quot; BorderBrush=&quot;Black&quot; CornerRadius=&quot;6&quot; 
    HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot;&gt;
    &lt;i:Interaction.Behaviors&gt;
        &lt;behaviors:Drag IsMovable=&quot;True&quot;/&gt;
    &lt;/i:Interaction.Behaviors&gt;
    &lt;Grid&gt;
        &lt;Image Source=&quot;4.jpg&quot; Width=&quot;100&quot; Height=&quot;100&quot; Stretch=&quot;UniformToFill&quot;/&gt;
        &lt;TextBlock Text=&quot;Image&quot; FontWeight=&quot;Bold&quot; FontSize=&quot;20&quot; 
            Foreground=&quot;Black&quot; HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot;/&gt;
    &lt;/Grid&gt;
&lt;/Border&gt;</pre></div></div>

<p><iframe src="/wp-content/uploads/2009/07/DragBehavior/" width="500" height="300"></iframe><br />
Code: <a onclick="javascript: pageTracker._trackPageview('/code/DragBehavior.zip'); " href="/wp-content/uploads/2009/07/DragBehavior/DragBehavior.zip">DragBehavior.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://joel.neubeck.net/2009/07/silverlight-3-drag-behavior/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
