做了一下午的布局,小小的总结了一下,看来之前挑了一个Grid拿出来单独讲算是讲对了,StackPanel、Canvas这两种布局方式个人认为不是很好用,但是又不能不说,毕竟在特定的时候这两种布局还是有用武之地的,所以趁着晚上无聊的时候利用一个实例说一说。

  MainPage.xaml.cs

MainPage.xaml.cs
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 SilverlightApplication1
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
bool trackingMouseMove = false;
Point mousePosition;
void OnMouseDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement element
= (FrameworkElement)sender;
mousePosition
= e.GetPosition(null);
trackingMouseMove
= true;
if (null != element)
{
element.CaptureMouse();
element.Cursor
= Cursors.Hand;
}
}
void OnMouseMove(object sender, MouseEventArgs e)
{
double deltaV = 0;
double deltaH = 0;
double newTop = 0;
double newLeft = 0;

FrameworkElement element
= (FrameworkElement)sender;
if (trackingMouseMove)
{
deltaV
= e.GetPosition(null).Y - mousePosition.Y;
deltaH
= e.GetPosition(null).X - mousePosition.X;
newTop
= deltaV + (double)element.GetValue(Canvas.TopProperty);
newLeft
= deltaH + (double)element.GetValue(Canvas.LeftProperty);
double width = (double)element.GetValue(Control.ActualWidthProperty);
double height = (double)element.GetValue(Control.ActualHeightProperty);
if (newTop < 0)
{
newTop
= 0;
}
if (newLeft < 0)
{
newLeft
= 0;
}
if (newTop > canvas1.Height - height)
{
newTop
= canvas1.Height - height;
}
if (newLeft > canvas1.Width - width)
{
newLeft
= canvas1.Width - width;
}

element.SetValue(Canvas.TopProperty, newTop);
element.SetValue(Canvas.LeftProperty, newLeft);
mousePosition
= e.GetPosition(null);
}
}
void OnMouseUp(object sender, MouseButtonEventArgs e)
{
FrameworkElement element
= sender as FrameworkElement;
trackingMouseMove
= false; element.ReleaseMouseCapture();
mousePosition.X
= mousePosition.Y = 0;
element.Cursor
= null;
}
}
}

代码没有加注释,喜欢研究拖拽功能的同学可以百度或者google一下,这里我们主要看一下代码中有Canvas和canvas1的地方,这两个地方都是通过Canvas来进行布局的,通过相关属性获得Canvas中控件的坐标值实现拖拽的功能。

  MainPage.xaml

MainPage.xaml
<Canvas Background="#46461F" x:Name="canvas1" Width="800" Height="600" MinWidth="400" MinHeight="400">
<Button ClickMode="Hover" MouseLeftButtonDown="OnMouseDown" MouseMove="OnMouseMove" MouseLeftButtonUp="OnMouseUp" Canvas.Left="50" Canvas.Top="50" Background="Red" FontSize="18" Width="160" Height="80">
<Button.Content>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">

<TextBlock Text="拖动我" VerticalAlignment="Center" Margin="10"></TextBlock>
</StackPanel>
</Button.Content>
</Button>
</Canvas>

 将执行拖拽的按钮放到Canvas中,在后台控制按钮的拖拽空间,这里注意一下<Button.Content>中的<stackPanel>,Button.Content相当于C#.Net中Button的Text属性,而在Silverlight中Content属性进行了扩展,这个属性可封装一些控件,如当前实例中,它封装了StackPanel布局控件及TextBlock标签控件,这里不进行深入讨论,重点是讨论Canvas及StackPanel。

  Canvas:实际上在这个实例中,Canvas发挥的作用上面已经阐述过了,它为可拖拽的按钮提供了一个可移动的区域,所以我们把Canvas称为容器控件。

  StackPanel:个人认为StackPanel布局控件更适用于一些嵌套布局,比如说上边的代码示例中虽然只放入了一个TextBlock,但是我们假象一下,如果我们在再放入一个image,那怎么样控制这两个控件的位置呢? 用Grid太浪费资源,用Canvas又不能很好的实现,很难办吧,所以这时我们就可以采用StackPanel布局来解决问题。

Orientation:决定封装到StackPanel中的控件是横向(Horizontal)排列还是纵向排列(Vertical).

HorizontalAlignment:水平排列样式

VerticalAlignment:垂直排列样式

通过上边这三个属性,基本上就可以将封装在StackPanel中的控件的位置及样式进行有效的调整,其他属性暂时还没有研究。

总体来看,在Web下的开发,Grid还是比较全面的,毕竟是与C#.Net中的Table同一级别的控件,所以从功能上看还是非常强大的,反观Canvas和StackPanel,这两个控件使用起来比较有局限性,强烈建议在今后的开发中多使用Grid布局控件。

 

 

 

posted on 2010-05-30 00:47  TerryAspx  阅读(1295)  评论(0编辑  收藏  举报