When you buy this book you support this site! - Thank You for your support!

May 21

Written by: Richard Waddell
5/21/2011 8:29 AM  RssIcon

 

image

LightSwitch removes so much tedium from programming that I’m hoping it can be integrated into any Silverlight application. Obviously that requires Custom Controls, so the focus becomes finding the best patterns for interaction between LightSwitch and Custom Controls.

My first goal was to incorporate drag and drop. I spent a lot of time trying to come up with scenarios that were not trivial but also wouldn’t take a long time to set up. But I kept running into a fuzzy area when I tried to think about the nature of the relationship between LightSwitch and the Custom Control. I was actually happy when I realized this because it meant I could start at the most basic level and work up. In other words, no hard thinking for awhile.

So, compulsive (or is it obsessive) that I am, even though Custom Controls are not totally new to me, I began by creating a New Data Screen linked to no table. To the screen I added a string property named BasicMessage and dragged it onto the screen layout, resulting in a TextBox bound to the BasicMessage property.  To supply the Custom Control I added a SilverLight Class Library project named CustomControls to the solution and to that project added a UserControl fumble-fingeredly named DragaArena consisting of a Beige 150 x 150 pixel Canvas.

To add DragaArena to the screen, I added a Custom Control under the BasicMessage TextBox. I changed the TextBox Display name to LightSwitch and the Custom Control Display Name to SilverLight.

image

To bind the Custom Control to DragaArena, click on Choices on the Custom Control properties panel. Note the name of the CustomControl is ‘DragArena’. This is important because CreateNew codebehind will be searching for this control in order to subscribe to the BallDropped event. I should have made it more distinguishable from the name of the SilverLight UserControl it encapsulates, ‘DragaArena’, but forewarned is forearmed.

image

(1) Click on Add Reference (2) Select CustomControls and click OK (3) Select DragaArena and click OK

image

Now we add a Label and a TextBox to DragaArena and bind them to BasicMessage. There’s also a ball we’re going to use for dragging and dropping:

<UserControl x:Class="CustomControls.DragaArena"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
    
    <Canvas x:Name="LayoutRoot" Background="#FFFFE6CD" Height="150" Width="150" >
		<sdk:Label Height="28" HorizontalAlignment="Left" x:Name="label1" Width="120" 
			Content="{Binding Screen.BasicMessage}" Canvas.Left="10" Canvas.Top="10" />
		<TextBox Height="23" HorizontalAlignment="Left" x:Name="textBox1" Text="{Binding Screen.BasicMessage, Mode=TwoWay}" 
			Width="120" Canvas.Left="10" Canvas.Top="30" />
		<Ellipse x:Name="ball" Fill="#FFF15F0A" Height="38" Stroke="Black" Width="41" MouseLeftButtonDown="ball_MouseLeftButtonDown" Canvas.Left="34" Canvas.Top="79"/>
	</Canvas>
</UserControl>

Note the binding is to Screen.BasicMessage. At runtime the Content property of label1 and the Text property of textBox1 are bound to the BasicMessage property of the Screen object, which is the parent of DragaArena, in this case CreateNew.

So now you can see the effect of the binding by entering some text:

image image

The drag and drop code is pretty straightforward considering I lifted 95% of it from Michael Washington. I feel unclean writing in the code-behind of a UserControl, but this is experimental code, and we’re all reasonable (hah – programmers) adults (hah – programmers) here so I’m sure the stigma won’t make me an outcast. Well, reasonably sure.

namespace CustomControls
{
    public partial class DragaArena : UserControl
    {
        private static Point _StartingDragPoint;
        public DragaArena()
        {
            InitializeComponent();
        }
        public event EventHandler BallDropped;
        protected virtual void OnBallDropped(EventArgs e)
        {
            if (BallDropped != null)
                BallDropped(this, EventArgs.Empty);
        }
        private void ball_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            FrameworkElement elem = sender as FrameworkElement;
            _StartingDragPoint = e.GetPosition(elem);
            elem.MouseMove += new MouseEventHandler(elem_MouseMove);
            elem.MouseLeftButtonUp += new MouseButtonEventHandler(elem_MouseLeftButtonUp);
            UpdateElementPosition(elem, e.GetPosition(this.LayoutRoot));
        }
        void elem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            FrameworkElement elem = sender as FrameworkElement;
            elem.ReleaseMouseCapture();
            elem.MouseLeftButtonUp -= new MouseButtonEventHandler(elem_MouseLeftButtonUp);
            elem.MouseMove -= new MouseEventHandler(elem_MouseMove);
            OnBallDropped(EventArgs.Empty);
        }
        void elem_MouseMove(object sender, MouseEventArgs e)
        {
            FrameworkElement elem = sender as FrameworkElement;
            Canvas canvas = elem.Parent as Canvas;
            UpdateElementPosition(elem, e.GetPosition(canvas));
        }
        private void UpdateElementPosition(FrameworkElement elem, Point newPoint)
        {
            Canvas.SetLeft(elem, newPoint.X - _StartingDragPoint.X);
            Canvas.SetTop(elem, newPoint.Y - _StartingDragPoint.Y);
        }
    }
}

You’ll need to add a reference to the CustomControls assembly. First select File View:

image

Add Reference:

image

Select CustomControls:

image

Happily frustrating my expectations, subscribing to the event is easy peasy, considering I lifted it from Karol Zador-Przylecki. See the code at the very end of the article for the specific example. Here’s the code I wrote based on it. This is the point where we’re searching for the LightSwitch CustomControl, ‘DragArena’ from which we’re going to create a proxy from which we can access the encapsulated SilverLight User Control, ‘DragaArena’, in OnDragArenaControlAvailable:

using CustomControls;
namespace LightSwitchApplication
{
    public partial class CreateNew
    {
        IContentItemProxy _arenaProxy = null;
        partial void CreateNew_Created()
        {
            _arenaProxy = this.FindControl("DragArena");
            _arenaProxy.ControlAvailable += OnDragArenaControlAvailable;
            _arenaProxy.ControlUnavailable += OnDragArenaControlUnvailable;
        }
        void OnDragArenaControlAvailable(object sender, ControlAvailableEventArgs e)
        {
            DragaArena arena = e.Control as DragaArena;
            arena.BallDropped += arena_BallDropped;
        }
        void OnDragArenaControlUnvailable(object sender, ControlUnavailableEventArgs e)
        {
            DragaArena arena = e.Control as DragaArena;
            arena.BallDropped -= arena_BallDropped;
        }
        void arena_BallDropped(object sender, EventArgs e)
        {
            BasicMessage = "Ball Dropped";
        }
        partial void CreateNew_Closing(ref bool cancel)
        {
            _arenaProxy.ControlAvailable -= OnDragArenaControlAvailable;
            _arenaProxy.ControlUnavailable -= OnDragArenaControlUnvailable;
        }
    }
}

After dropping the ball:

image

So if you can handle everything through subscribing to events on the Custom Control you don’t need to give the Custom Control any knowledge of its parent other than the late binding in XAML.

Stay tuned for an example where the dragged objects represent data from Screen and I totally rip off more code from Michael Washington.

Tags:
Categories:

4 comment(s) so far...


Gravatar

Re: Drag and Drop and Events in LightSwitch Custom Controls

Great! Can't wait to see what you are going to do next. I will also hound you until I get a code sample from you to post to the site :)

By Michael Washington on   5/21/2011 2:00 PM
Gravatar

Re: Drag and Drop and Events in LightSwitch Custom Controls

Just to share.. I found a great use for drag and drop in a LS custom control & managed to get it working early this year..

While dragging and dropping a file (or more) off the Desktop into a Desktop (WinForm/WPF) application is nothing new.. Enabling users to do the same with a web-based application is.. imho, simply awesome!

How many websites can you find out there that enables you to do such things? Especially when it comes to uploading files into a website... Most will only allow you to pick one file at a time.

My implementation allows my users to select as many file as they want from their desktop (you know how people love to place everything on their Desktop!) and drag-and-drop all of them at once into my web-based LS app.

Alas, that was all done in LS Beta 1. I wonder what the release version has in store.. would I be able to achieve the same or better with LS 2011?

By Faris Wong on   6/22/2012 6:10 AM
Gravatar

Re: Drag and Drop and Events in LightSwitch Custom Controls

Very Good information here. thanks !

However Can you tell if it is possible to drag an item from a "light switch control" like a list and drop it over to
a silverlight custom control.

I wish to be able to select an item from a "lightswitch" grid on the right and drag that item over and drop it on to a Silverlight Tile Layout control.

So imagine dragging a name from a list and when dropped over to a Silverlight "Tile" on the right, resulting into the Tile loading the picture of the person ( whose name you just dragged ).

something like that ..
thanks !

cheers
Kuldeep

By kuldeep on   6/22/2012 6:11 AM
Gravatar

Re: Drag and Drop and Events in LightSwitch Custom Controls

Hi Kuldeep,

Glad the article was helpful. As to your question, that scenario has not come up for me so while it's probably possible I've never worked out how to do it.

Richard

By Richard Waddell on   6/22/2012 6:13 AM

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment   Cancel 
Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation