Silverlight中的拖拽实现的图片上传---1
传统的上传都是打开对话框,选择文件,然后点击上传。步骤比较多。使用Silverlight做的文件上传如下图所示:
直接左键鼠标,拖拽过去就OK了。如下图:
这边文章里不能完全实现服务器端的上传,以及一些效果的实现,使用Animation。。。。
废话多了。。。
首先是创建一个silverlight应用程序,如下图。
然后主页面中创建一个Grid,注意第一要把AllowDrop设置为True。。
接下来设置Grid的背景:
<Grid.Background>
<LinearGradientBrush StartPoint="0.5,0.0" EndPoint="0.5,1.0">
<GradientStop Offset="0.0" Color="White" />
<GradientStop Offset="1.0" Color="#FF404040" />
</LinearGradientBrush>
</Grid.Background>
最后是列的定义。
在第一列中放入一个Canvas,用来显示拖上去的图片。
<Canvas Grid.Column="0" x:Name="PhotoBoard" Height="184" Width="264" >
<!-- Photos dynamically inserted here -->
</Canvas>
后台代码:
后台代码主要是实现了当有文件放到页面时,Silverlight会把文件放到一个队列中。然后把每个文件显示在页面。
事件的委托:
// Register a handler for Rendering events
CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
// Register a handler for Drop events
LayoutRoot.Drop += new DragEventHandler(LayoutRoot_Drop);
文件的入队。
void LayoutRoot_Drop(object sender, DragEventArgs e)
{
// Hide the instructional text
Instructions.Visibility = Visibility.Collapsed;
// Queue the FileInfo objects representing dropped files
if (e.Data != null)
{
FileInfo[] files = e.Data.GetData(DataFormats.FileDrop) as FileInfo[];
foreach (FileInfo fi in files)
{
_files.Enqueue(fi);
}
}
}
实现把每个文件都显示到页面的方法:
private void CompositionTarget_Rendering(Object sender, EventArgs e)
{
if (_files.Count != 0)
{
// Create a photo
FileInfo fi = _files.Dequeue();
CreatePhoto(fi);
}
}
CreatePhone:=》主要是把一个Bitmap的图换成一个writeable的来显示:
using (Stream stream = fi.OpenRead())
{
try
{
// Decode the image bits
BitmapImage bi = null;
try
{
bi = new BitmapImage();
bi.SetSource(stream);
}
catch (OutOfMemoryException)
{
// Just in case
_files.Clear();
MessageBox.Show("Out of memory");
return;
}
catch (Exception)
{
// Probably came here because the image isn't valid; ignore
return;
}
// Compute the image dimensions
double cx = (double)bi.PixelWidth;
double cy = (double)bi.PixelHeight;
if (cx >= cy)
{
// Set width to 400 and compute height
cy *= 400.0 / cx;
cx = 400.0;
}
else
{
// Set width to 300 and compute height
cy *= 300.0 / cx;
cx = 300.0;
}
// Create a WriteableBitmap the same size as the image to be displayed
Image image = new Image();
image.Source = bi;
WriteableBitmap wb1 = new WriteableBitmap((int)cx, (int)cy);
ScaleTransform transform = new ScaleTransform();
transform.ScaleX = cx / bi.PixelWidth;
transform.ScaleY = cy / bi.PixelHeight;
wb1.Render(image, transform);
wb1.Invalidate();
// Now make a copy of the WriteableBitmap so the BitmapImage can be garbage-collected (important!)
WriteableBitmap wp3 = new WriteableBitmap((int)cx, (int)cy);
for (int i = 0; i < wp3.Pixels.Length; i++)
wp3.Pixels[i] = wb1.Pixels[i];
wp3.Invalidate();
Image thumbnail = new Image();
thumbnail.Width = cx;
thumbnail.Height = cy;
// Create a Border containing an image
Border item = (Border)XamlReader.Load(String.Format(CultureInfo.InvariantCulture,
_template,
_count++,
(PhotoBoard.ActualWidth - cx) / 2, (PhotoBoard.ActualHeight - cy) / 2, // Initial position (center of workspace)
cx + _border, cy + _border, // Width and height of photo border
(cx + _border) / 2, (cy + _border) / 2, // Center of rotation
cx, cy)); // Width and height of photo
// Assign the WriteableBitmap to the Image
(item.Child as Image).Source = wp3;
// Add the photo to the scene
PhotoBoard.Children.Add(item);
// Compute spatial parameters
double x = _rand.NextDouble() * (PhotoBoard.ActualWidth - cx);
double y = _rand.NextDouble() * (PhotoBoard.ActualHeight - cy);
double angle = _angle - (_rand.NextDouble() * _angle * 2);
// Position the photo and make it visible
item.SetValue(Canvas.LeftProperty, x);
item.SetValue(Canvas.TopProperty, y);
(item.FindName("SpinTransform") as RotateTransform).Angle = angle;
item.Visibility = Visibility.Visible;
下面是给这个图片添加一个动画功能使其旋转:
主页面需要添加的XAML:
<UserControl.Resources>
<Storyboard x:Name="spinStoryboard">
<DoubleAnimation Storyboard.TargetName="projection" RepeatBehavior="Forever"
Storyboard.TargetProperty="RotationY" From="0" To="360" Duration="0:0:3">
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="projection" RepeatBehavior="Forever"
Storyboard.TargetProperty="RotationZ" From="0" To="360" Duration="0:0:30">
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="projection" RepeatBehavior="Forever"
Storyboard.TargetProperty="RotationX" From="0" To="360" Duration="0:0:40">
</DoubleAnimation>
</Storyboard>
<Storyboard x:Name="colboard">
</Storyboard>
</UserControl.Resources>
<Border CornerRadius="2" Padding="10"
BorderThickness="4" Margin="1,1,0,-4" HorizontalAlignment="Left" Width="326">
<Border.Projection>
<PlaneProjection x:Name="projection">
</PlaneProjection>
</Border.Projection>
<Canvas Grid.Column="0" x:Name="PhotoBoard" Height="184" Width="264" >
<!-- Photos dynamically inserted here -->
</Canvas>
</Border>
后台代码只需要在图片显示时让动画开始播放就行了。
spinStoryboard.Begin();
运行效果: