Silverlight 2 Drag and Scroll Image
This is somewhat based on Shawn Wildermuth’s blog post for drag and drop. I had two problems with his post.
- I’m not scrolling a canvas.
- If your mouse leaves the control with the button down you are still dragging when your mouse reenters the control.
So here’s my tweaked version:
The control has a scroll viewer as the root element and a simple grid with one column and one row inside that. There is a large image inside the grid cell. There are events firing from the grid’s mouse down, up, move and grid leave events.
<UserControl x:Class="TestMouseScroll.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="300" Height="300" Background="Transparent" >
<ScrollViewer
x:Name="scrollViewImage"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible" >
<Grid
x:Name="gridImageContainer"
Background="Gray"
ShowGridLines="True"
MouseLeftButtonDown="grid_MouseLeftButtonDown"
MouseLeftButtonUp="grid_MouseLeftButtonUp"
MouseMove="grid_MouseMove"
MouseLeave="grid_MouseLeave"
>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Image Source=http://www.inetres.com/gp/military/infantry/rifle/M107/M107_1.jpg
Grid.Row="0" Grid.Column="0" >
</Image>
</Grid>
</ScrollViewer>
</UserControl>
The code looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace TestMouseScroll
{
public partial class Page : UserControl
{
bool isTracked = false;
Point startDrag;
public Page()
{
InitializeComponent();
}
private void grid_MouseLeftButtonDown(object sender,
MouseButtonEventArgs e)
{
isTracked = true;
// Get the starting mouseposition based on
// where the mouse is positioned on the image,
// not the relative postion inside the scroller
startDrag = e.GetPosition(gridImageContainer);
}
private void grid_MouseLeftButtonUp(object sender,
MouseButtonEventArgs e)
{
isTracked = false;
}
private void grid_MouseLeave(object sender, MouseEventArgs e)
{
isTracked = false;
}
private void grid_MouseMove(object sender, MouseEventArgs e)
{
if (isTracked)
{
Point newPos = e.GetPosition(scrollViewImage);
try
{
scrollViewImage.ScrollToHorizontalOffset(startDrag.X - newPos.X);
scrollViewImage.ScrollToVerticalOffset(startDrag.Y - newPos.Y);
}
catch { }
}
}
}
}
I think this is pretty straight forward and works nicely for me.
Incidentally, the Barrett was a sniper rifle introduced into the T/E of my unit some time between ‘91 and ‘93. I don’t know exactly when but it wasn’t there the first time I deployed and it was the second time. Used primarily as a vehicular countermeasure, it is still in use today. It’s an awesome addition to any infantry or STA unit firing accurately in the multi-kilometer range (v/s ~1,000 meters for standard 7.62). Note that the kevlar helmet has a USMC Corporal’s rank insignia on it. That’s E4. So a 21 year old professional warrior is trained and deployed with this little monster. Happens every day. There are people who have served in Congress and the House for many decades who cannot be trusted with a spitwad in a McDonalds straw but they have the power to send these fine gentlemen into harms way to voluntarily perform honorably and under stresses and conditions that would make normal men soil themselves. My point is that there ought to be a qualification process to be allowed to make our laws similar to the qualification it takes to become a Marine Sniper. An old Marine can wish…