Archive for July, 2010

Behavior to process an Image Drop from file system to Image Source

This behavior is used to set the source of a silverlight image control when an image is dropped from the file system onto a UIElement in the Silverlight application.
Sample Application:

Install Microsoft Silverlight

How:

  • Register to the Drop event on the AssociatedObject.
  • The dropped file is processed to a bitmap image from a filestream. I took advantage of using the extension method for processing a file drop which can be seen here.
  • Set the Source of the TargetImage to be the dropped image.

Code:

public class ImageDropBehavior : Behavior<UIElement>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.Drop +=
                new DragEventHandler(AssociatedObject_Drop);
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.Drop -=
                new DragEventHandler(AssociatedObject_Drop);
        }

        private void AssociatedObject_Drop(object sender, DragEventArgs e)
        {
            Func<FileStream, BitmapImage> func = (stream) =>
            {
                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.SetSource(stream);

                return bitmapImage;
            };

            var droppedImage =
                e.ProcessDragEventArgsTo<BitmapImage>(func, _ => { });
            if (droppedImage != null)
            {
                TargetImage.Source = droppedImage;
            }
        }

        public static readonly DependencyProperty TargetImageProperty =
            DependencyProperty.Register("TargetImage",
            typeof(Image),
            typeof(ImageDropBehavior),
            new PropertyMetadata(null));

        public Image TargetImage
        {
            get { return (Image)GetValue(TargetImageProperty); }
            set { SetValue(TargetImageProperty, value); }
        }
    }
}

Using the behavior:

  • Attach the behavior to a UIElement.
  • The AllowDrop property needs to be set to true on the UIElement the behavior is attached to else the Drop event will never be raised.
  • Element bind the TargetImage property on the behavior to an Image.
  • See the behavior being used in blend:

Notes:

  • If the target image has data binding, this behavior will remove the binding when it sets the image source.
  • Will only work for Silverlight supported images. At the point of writing these are jpg and png.
public class ImageDropBehavior : Behavior<UIElement>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Drop += new DragEventHandler(AssociatedObject_Drop);
}

protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Drop -= new DragEventHandler(AssociatedObject_Drop);
}

private void AssociatedObject_Drop(object sender, DragEventArgs e)
{
Func<FileStream, BitmapImage> func = (stream) =>
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);

return bitmapImage;
};

var droppedImage = e.ProcessDragEventArgsTo<BitmapImage>(func, _ => { });
if (droppedImage != null)
{
TargetImage.Source = droppedImage;
}
}

public static readonly DependencyProperty TargetImageProperty =
DependencyProperty.Register(“TargetImage”,
typeof(Image),
typeof(ImageDropBehavior),
new PropertyMetadata(null));

public Image TargetImage
{
get { return (Image)GetValue(TargetImageProperty); }
set { SetValue(TargetImageProperty, value); }
}
}

Generic processing of a Drag event from the file system

This is an extension method to help a user in processing a DragEventArgs to a object type of their choice.

How

  • Take a function to create the required Type from a FileStream.
  • Take an Action to handle an exception.
  • Check that the drop array contains a FileDrop.
  • Select the First FileInfo and open a FileStream.
  • Execute createAction with this FileStream. If this fails the exception will be handled by the onFailed callback.

The Code:

Return top