针对Silverlight玩转控件和二——Canvas布局这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展canvas–如何在Silverlight中绘制箭头、MySilverlight系列
针对Silverlight玩转控件和二——Canvas布局这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展canvas – 如何在Silverlight中绘制箭头、My Silverlight系列(10)—— Silverlight中的InkCanvas、Silverlight 2学习教程(九):Silverlight 2 beta2 新控件介绍之 TabControl 控件、Silverlight 2学习教程(二):开发简单的Silverlight 2应用程序等相关知识,希望可以帮助到你。
本文目录一览:- Silverlight玩转控件(二)——Canvas布局(canvas controller)
- canvas – 如何在Silverlight中绘制箭头
- My Silverlight系列(10)—— Silverlight中的InkCanvas
- Silverlight 2学习教程(九):Silverlight 2 beta2 新控件介绍之 TabControl 控件
- Silverlight 2学习教程(二):开发简单的Silverlight 2应用程序
Silverlight玩转控件(二)——Canvas布局(canvas controller)
在接下来的几篇文章中,我将来介绍Silverlight相关的布局知识。
在Silverlight中,布局主要有三种方式:
1. Cavas
2. StackPanel
3. Grid
在传统的ASP.NET中,我们知道,布局通常是通过传统的CSS+DIV来予以实现,但是在Silverlight中,我们更多的是通过布局控件+Style来予以实现,至少我的习惯是这样的。Style其实很类似于CSS。
好,转入正题,在这篇文章中,我主要来介绍Canvas控件的用法。
首先,让我们新建一个Silverlight 2的项目:
然后是这样:
好,如果没有错误的话,我们应该已经新建了一个Silverlight 2的项目文件,在项目中,我们可以看到:
我们来大致介绍一下:SilverlightApplication.Web是一个测试的页面文件。
这个就要从Silverlight的本质来说起,我不想为Silverlight拉广告,说Silverlight有哪里哪里的好,与传统的页面和Flash相比有什么优点之类的话,这些仁者见仁,智者见智。我也不妄加评论。我只是专心学我的微软技术就好了。
Silverlight其实我们可以把它当成一个用户控件的作用来理解,他不能独立运行,而需要一个ASP.NET网站或者HTML页面作为宿主来运行。而这个SilverlightApplication.Web下的SilverlightApplication1TestPage.aspx和SilverlightApplicationTestPage.html就是这个Silverlight项目的宿主测试页面。
在Silverlight编译后,会生成一个dll的文件,我们可以在Web应用中导入这个dll文件,就像我们导入其他的第三方控件一样,然后来使用我们所创建的Silverlight项目。
我们在第一次运行之后看看项目中的变化:
我们可以发现,多了一个xap文件,而在SilverlightApplication1TestPage.aspx中,我们可以发现玄机:
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> <div style="height:100%;"> <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SilverlightApplication1.xap" MinimumVersion="2.0.31005.0" Width="100%" Height="100%"/> </div>
好了,我想大多数人都应该知道这个Silverlight是如何启动的了。不再赘言。
现在开始主题,使用Canvas来布局。
Canvas——中文的翻译是帆布,油画(布)。这个很形象,在Silverlight中,Canvas就像一张油布一样,所有的控件都可以堆到这张布上。
而使用Canvas布局和使用传统的ASP.NET非常类似。
我们回顾一下我们使用ASP.NET的时候,我们创建一个Button,使这个Button距页面左侧和顶部分别是50和50:
<head runat="server"> <title></title> <style type="text/css"> .newStyle1 { margin-left:50px; margin-top:50px; } </style> </head> <body> <form id="form1" runat="server"> <div> <asp:Button ID="Button1" runat="server" Text="Button" CssClass="newStyle1" /> </div> </form> </body>
好了,接下来让我们看下在Silverlight的Canvas布局方式中,我们该如何去实现同样的效果.
在传统的ASP.NET中,我们是把整个Web页面作为一个画布,在上面摆置各种Web控件。其实在Silverlight的Canvas布局中也是一样,我们也只是需要设置于Canvas的距离即可。
但是更为简单,毕竟抛弃了我们编程人员都讨厌的CSS,而使用了属性,我们来看:
<Canvas> <Button Content="Button" Width="70" Height="30" Canvas.Left="50" Canvas.Top="50"></Button> </Canvas>
看下效果:
恩,不错,但是纯白色的背景很难看诶!换个背景色:
<Canvas Background="LightBlue"> <Button Content="Button" Width="70" Height="30" Canvas.Left="50" Canvas.Top="50"></Button> </Canvas>
呵呵,别骂我,这么简单的也往上写!我只是觉得他背景难看换一下罢了!
大家还记得组合模式么?在布局中,这个模式简直太经典了!
恩!详细的我就不说了,要不又该跑题了!在Silverlight中,也是一样,布局控件一样是可以嵌套的。
我们来看个例子:
<Canvas Background="LightBlue"> <Canvas Canvas.Left="50" Canvas.Top="50"> <Button Canvas.Left="0" Canvas.Top="0" Content="Button" Width="70" Height="30"></Button> </Canvas> </Canvas>
我们可以清楚地看到,即使是Button中设置了Canvas.Left=”0”和Canvas.Top=”0”,这个Button依然与页面的边框有距离,原因就在于Canvas嵌套。这个我就不解释了。
在我们使用Canvas布局时,智能提示会给出这样的东西:
ZIndex,这究竟是个什么东西呢?让我们来看这样一个例子:
<Canvas Background="LightBlue"> <Button Content="Button" Canvas.Left="20" Width="60" Height="30" Canvas.Top="30"></Button> <Button Content="Test" Canvas.Left="20" Width="60" Height="30" Canvas.Top="30"></Button> </Canvas>
效果如下:
大小,位置都相同,后创建的Button当然覆盖前一个Button,我们可以理解。
然而使用了ZIndex属性:
<Canvas Background="LightBlue"> <Button Content="Button" Canvas.ZIndex="2" Canvas.Left="20" Width="60" Height="30" Canvas.Top="30"></Button> <Button Content="Test" Canvas.ZIndex="1" Canvas.Left="20" Width="60" Height="30" Canvas.Top="30"></Button> </Canvas>
这就得到了这样的效果:
这就是ZIndex的作用,我们知道,我们生活在一个三维空间里(我们不考虑四维的空间)。我们声明的Canvas.Top和Canvas.Left只描述了其中的二维,而ZIndex则描述的是第三维。也就是我们在空间直角坐标系的Z轴。
好,最后说明Canvas的最后一个用途。封装一组控件,还记得在Winform的应用中,我们经常使用Panel来封装一组控件,在Silverlight中,我们最常使用的就是Canvas.
而且,在Silverlight中,布局控件依然支持一系列的事件:
做个简单的例子吧:
<Canvas Background="LightBlue" MouseEnter="Canvas_MouseEnter" Name="Canvas1" > <Button Content="Button" Canvas.Left="20" Canvas.Top="20"></Button> <Button Content="Button" Canvas.Left="20" Canvas.Top="60"></Button> <Button Content="Button" Canvas.Left="20" Canvas.Top="100"></Button> </Canvas>
然后看后台代码:
private void Canvas_MouseEnter(object sender,MouseEventArgs e) { foreach (Control c in this.Canvas1.Children) { Button b = c as Button; if (b != null) { b.Content = "按钮"; } } }
好了,看看效果吧:
好了,搞定!
原文:http://www.cnblogs.com/kym/archive/2009/02/02/1382756.html
canvas – 如何在Silverlight中绘制箭头
这大致是我需要的:
[TextBox] <----- [Button]
我试图将Line子类化并在最后添加几行,但是类是密封的.
你将如何构建一个在X1,Y1和X2,Y2之间绘制箭头的自定义控件?
解决方法
Lines with Arrows @ Petzold Book Blog
– 编辑 –
好的 – 这是另一种方法:
创建用户控件:
<UserControl x:xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Canvas x:Name="LayoutRoot"> <Line x:Name="Cap" /> <Line x:Name="Connector" /> <Line x:Name="Foot" /> </Canvas> </UserControl>
使用以下代码:
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 ArrowsAndDaggersLibrary { public partial class ArrowsAndDaggersUC : UserControl { private Point startPoint; public Point StartPoint { get { return startPoint; } set { startPoint = value; Update(); } } private Point endPoint; public Point EndPoint { get { return endPoint; } set { endPoint = value; Update(); } } public ArrowsAndDaggersUC() { InitializeComponent(); } public ArrowsAndDaggersUC(Point StartPoint,Point EndPoint) { InitializeComponent(); startPoint = StartPoint; endPoint = EndPoint; Update(); } private void Update() { //reconfig Connector.X1 = startPoint.X; Connector.Y1 = startPoint.Y; Connector.X2 = endPoint.X; Connector.Y2 = endPoint.Y; Connector.strokeThickness = 1; Connector.stroke = new SolidColorBrush(Colors.Black); Cap.X1 = startPoint.X; Cap.Y1 = startPoint.Y; Cap.X2 = startPoint.X; Cap.Y2 = startPoint.Y; Cap.strokeStartLineCap = PenLineCap.Triangle; Cap.strokeThickness = 20; Cap.stroke = new SolidColorBrush(Colors.Black); Foot.X1 = endPoint.X; Foot.Y1 = endPoint.Y; Foot.X2 = endPoint.X; Foot.Y2 = endPoint.Y; Foot.strokeEndLineCap = PenLineCap.Triangle; Foot.strokeThickness = 20; Foot.stroke = new SolidColorBrush(Colors.Black); } } }
像这样称呼它:
LayoutRoot.Children.Add(new ArrowsAndDaggersUC(new Point(200,200),new Point(300,400)));
并且你将在每行的末尾有1px笔划线和20px笔划三角形.
– 编辑 –
@ Number8有一个关于如何修改用户控件的问题,以便大写字母指向与该行相同的方向.
修改用户控件的Xaml,如下所示:
<UserControl x:xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Canvas x:Name="LayoutRoot"> <Line x:Name="Cap"> <Line.RenderTransform> <RotateTransform x:Name="CapRotateTransform" /> </Line.RenderTransform> </Line> <Line x:Name="Connector" /> <Line x:Name="Foot"> <Line.RenderTransform> <RotateTransform x:Name="FootRotateTransform" /> </Line.RenderTransform> </Line> </Canvas> </UserControl>
然后,更改“更新”方法以获取线条的角度并将大写字母旋转到该角度:
private void Update() { double angleOfLine = Math.atan2((endPoint.Y - startPoint.Y),(endPoint.X - startPoint.X)) * 180 / Math.PI; Connector.X1 = startPoint.X; Connector.Y1 = startPoint.Y; Connector.X2 = endPoint.X; Connector.Y2 = endPoint.Y; Connector.strokeThickness = 1; Connector.stroke = new SolidColorBrush(Colors.Black); Cap.X1 = startPoint.X; Cap.Y1 = startPoint.Y; Cap.X2 = startPoint.X; Cap.Y2 = startPoint.Y; Cap.strokeStartLineCap = PenLineCap.Triangle; Cap.strokeThickness = 20; Cap.stroke = new SolidColorBrush(Colors.Black); CapRotateTransform.Angle = angleOfLine; CapRotateTransform.CenterX = startPoint.X; CapRotateTransform.CenterY = startPoint.Y; Foot.X1 = endPoint.X; Foot.Y1 = endPoint.Y; Foot.X2 = endPoint.X; Foot.Y2 = endPoint.Y; Foot.strokeEndLineCap = PenLineCap.Triangle; Foot.strokeThickness = 20; Foot.stroke = new SolidColorBrush(Colors.Black); FootRotateTransform.Angle = angleOfLine; FootRotateTransform.CenterX = endPoint.X; FootRotateTransform.CenterY = endPoint.Y; }
My Silverlight系列(10)—— Silverlight中的InkCanvas
有许多人喜欢手写板或者涂鸦板之类的东西,而并不怎么喜欢输入法,因此Microsoft专门有Ink这个东西用于处理鼠标画图。不得不说这个东西功能十分的强大,也让许多用户使用起来非常方便,用微软开发出来的很多Ink与Bitmap结合的API,即使不会用Photoshop的人也能轻松打开一张图片,然后在自己喜欢的地方写上一段话或者签个名什么的。这个功能,Winform上面有,WPF上面也有,当然Silverlight上也有,只不过作为起步不久的Silverlight版Ink,功能尚不够强大,目前能够开放给我们使用的,只有InkPresenter这一个控件。
也许开发WPF的人都没怎么听说过这个控件而只听说过InkCanvas——那是一个在WPF上对Ink功能封装得非常完善的控件,我们可以使用它进行画图和橡皮擦等一系列的事情。当然,如果你去研究过这个控件,你就可以发现其实它其实是通过DataBinding在InkPresenter上进行了进一步的封装。由于WPF与Silverlight不同的继承结构,恐怕在Silverlight上很难照搬WPF上那一套,即我们不能对其进行一对一的Port,所以如果要在Silverlight上实现一个InkCanvas,就要另辟蹊径。
如果你使用过WPF的InkCanvas控件,你将会发现它支持EraseByPoint,EraseBystroke,Ink三种模式,而且支持复制、粘贴,而且可以轻松地扩展出撤销与重做两个功能。但是后面的一系列功能,不是InkCanvas的核心功能,只要前三者得以实现,那么这个InkCanvas就可以正常的运作了。那么,我们首先从这三种模式中用于画图的Ink模式说起。
InkCanvas的核心,其实在于它内部的InkPresenter,在Silverlight中InkPresenter仅仅是Canvas的子类,只不过它多了strokes这么一个属性用于存储和展示画上去的所有stroke。因此,它把如何生成一个stroke的问题完全留给了我们。先来看一下stroke的定义:
其中DrawingAttributes这个属性是用于描述画笔的颜色的,而StylusPoints描述了stroke内点的集合。学过数学的人都知道,线是由点组成的,因此只要我们找到了应该插入到这个stroke中所有的点,那么生成一个新的stroke不在话下。所幸MouseEventArgs中,有一个StylusDevice只读属性,而它的一个公共方法public StylusPointCollection GetStylusPoints(UIElement relativeto)可以在鼠标事件触发的时候,得到这些“点”的集合。我们只需要为InkPresenter加上MouseLeftButtonDown,MouseMove,MouseLeftButtonUp三个handler,那么我们就可以在鼠标进行轨迹上把那些点加到线上,并将这条线加入到InkPresenter这个“面”里。代码比较多,最后我会把工程放在下面,就不一段一段的贴了。
其实这个Ink模式,不算什么难点,而后面这个EraseBystroke也相对简单,最笨的方法就是遍历InkPresenter内所有的stroke,然后一一检验它是否与我们的"Eraser"有交叉,如果有,则将它Remove。但是,最后这个EraseByPoint可没那么容易了,因为当橡皮将一条线拦腰截断的时候,不但要把擦掉的部分去掉,还要把余下的两段保留在strokes这个strokeCollection中,这才能达到一分为二的效果。我最初在实现这个功能的时候,由于设计的算法时间复杂度居高不下,造成如果相交的线过多,或者橡皮拖动太快,就会出现卡死的现象。在与微软silverlight开发小组的stefan swick交流之后,他决定实现这一功能,并且将其做成一个Custom Control。昨天他告诉我他把这个东西做好了,要我去他的Blog上下载。今天我仔细研究了他的算法,发现这个算法与我的算法有一个最大的不同之处就是:我在将一条线一分为二的过程中,完全是按照从前向后的顺序,将每个点一一挎贝并缓存,从前向后判断这个点是否被橡皮擦中,如果被擦中的话,马上生成一个新的stroke,把旧的加入strokes内,并对新的stroke进行上述相同的操作。而stefan的算法则分为了两个部分,首先从前向后把前面没有被擦中的点取出来存到一个新的stroke中,然后停止,再从后往前寻找后面的点,将没有被擦中的点加入到一个新的stroke中,直到遇到被擦中的点停止。这样的话,可以保证一个stroke可以被一分为二。
经过我的测试,执行并没有什么问题。但是由于我们向stroke中插入点,完全依赖于MouseMove事件,如果我们的鼠标移动速度过快,那么被插入的这些本就离散的点,它们之前的间隔会变得更大。这在Ink模式下不会有什么问题,但是在EraseByPoint模式下,就会因被去掉的点附近没有其他的点,而一次性擦掉很大的一段,这是由于我们在插入点和擦除的时候没有做任何的优化造成的,希望这个问题能得到解决。
大家可以到http://blogs.msdn.com/swick/archive/2008/11/30/erasing-ink-in-silverlight-2.aspx去看stefan的原文,那里提供工程原件的下载,我就不再多此一举把它上传到博客园来浪费空间了。至于上面提到的问题,如果大家有什么优化的方式和算法,希望可以告诉我们,谢谢!
Silverlight 2学习教程(九):Silverlight 2 beta2 新控件介绍之 TabControl 控件
Silverlight 2 beta2 新控件之TabControl
Silverlight 2 为设计人员和开发人员提供了可在应用程序中使用的一套控件,通过 Expression 工具,我们可以设置这些控件的外观。在 Silverlight 2 的 Beta 2中,又增添一个新的控件:TabControl
TabControl 控件包含在 System.Windows.Controls.Extended 类库中,而不是包含在 Silverlight 的核心类库中。要使用 TabControl 控件,需要添加对 Extended 程序集的引用才可以使用。在 Expression Blend 中,你可以在Asset Library的自定义控件中找到 TabControl。
实际上,自定义控件中包括 TabControl 和TabItem 2 个控件。在 Blend 中,需要先把TabControl控件拖到设计器界面中,然后在 Objects and Timeline 浏览器中双击 TabControl 控件,就会看到在这个控件周围有一条黄色的边框,表示该控件目前处于选中状态。此时,你必须再回到 Asset Library ,转到 Asset Library 控件并双击它,它就会添加到 TabControl的子控件中,可以添加多个。
最终的XAML文件可能是下面的样子:
<ex:TabControl TabStripPlacement="Bottom" VerticalAlignment="Top"
Width="231.148" Height="156.611" HorizontalAlignment="Left"
x:Name="tabstrip1">
<ex:TabItem Width="75" Height="20">
</ex:TabItem>
<ex:TabItem Width="75" Height="20" Header="Second">
</ex:TabItem>
<ex:TabItem Width="75" Height="20" Header="Third">
</ex:TabItem>
</ex:TabControl>
注意 TabControl 控件的 "ex" 名称空间,默认情况下可能是 “System_Windows_Controls”,这是添加 TabControl 控件时自动加上去的,这个名称空间实际上是加在 XAML 文件的 root 节点上的,可以改成任何想要的名称。
TabControl 有一些属性,其中一个最重要的属性是 TabStripPlacement ,这个属性允许我们设置 TabItems (tabs) 显示的方向:Top,Left,Right,或 Bottom。我们可以在 XAML 中设置可以在运行时使用 Dock 枚举设置。
每一个 TabItem 也有2个重要的属性:Header 和 Content,Header 设置标签(tab)本身的内容,而Content 设置 TabItem 里面的具体内容。它可以设置成文本值,也可以设置成其他那女人,如一些按钮控件等。例如
<ex:TabItem Width="75" Height="20" Header="Third">
<StackPanel Orientation="Vertical">
<TextBox x:Name="yourname" />
<Button Content="Click me" Click="Button_Click" />
<TextBlock x:Name="resulttext" />
</StackPanel>
</ex:TabItem>
如果要设置Header的内容,可以明确使用 TabItem.Header,例如
<ex:TabItem Width="75" Height="20">
<ex:TabItem.Header>
<Button Content="foo" />
</ex:TabItem.Header>
<Button Content="Click Me" Click="Button_Click_1"/>
</ex:TabItem>
源自:http://timheuer.com/blog/archive/2008/06/04/silverlight-2-introduces-tabcontrol.aspx
Silverlight 2学习教程(二):开发简单的Silverlight 2应用程序
准备工作做好了之后,下面就可以开始进行Silverlight 2的应用程序的开发了。
启动VS2008,“新建项目”,可以看到“项目类型”下面有“Silverlight”,选择“Silverlight”,在右边的模板里面可以看到“已安装的模板”列出了“Silverlight Application”和“Silverlight Class Library”两种类型的模板。
选择“Silverlight Application”模板,出现下面的对话框:
由于Silverlight应用程序目前还无法单独运行,它必须嵌入页面里面,通过object标签元素来启动它,所以,在创建“Silverlight Application”的时候,VS会提示你选择一种运行Sliverlight程序的方法。如果选择“Add a new Web to the solution for hosting the control”,此时需要创建一个Web站点:既可以创建Web网站,也可以创建Web Application类型的项目,如下图:
如果选择“Generate an HTML test page to host Silverlight within this project”的方法,则会在项目文件夹的ClientBin下创建一个TestPage.html文件,以用来运行Silverlight程序。
下面,我们选择“Web Application Project”的方法来做一个简单的例子。单击“ok”按钮后,出现下面的界面:
可以通过上下箭头切换设计区和代码区的位置,也可以通过右边蓝色框里面的按钮隐藏区域和横向、纵向切分窗口。
在XAML代码区的<Grid></Grid>标记之间,输入下面的代码:
< TextBlock Canvas.Top ="10" Canvas.Left ="20" > 请输入您的姓名: </ TextBlock >
< TextBox x:Name ="UserInput" Width ="200" Height ="30" Canvas.Top ="40" Canvas.Left ="20" ></ TextBox >
< TextBlock x:Name ="Msg" Canvas.Top ="90" Canvas.Left ="20" Foreground ="Navy" FontSize ="48" ></ TextBlock >
< Button Click ="Button_Click" Content ="单击我" FontSize ="24" Width ="160" Height ="60" x:Name ="BtnTest" Canvas.Top ="160" Canvas.Left ="20" ></ Button >
</ Canvas >
在输入的过程,VS出现智能提示,方便输入。
在XAML代码区,单击鼠标右键,可以从右键菜单上选择“查看代码”,切换到代码区域,以处理用户单击按钮执行的任务。也可以在事件名称上选择“导航到事件处理程序”来进入代码输入界面:
当前XAML的所有成员都可以从右边的下拉列表中进行查找到。
在Button_Click的事件处理函数内,输入以下的内容:
if (UserInputContent.Equals(String.Empty))
{
this .Msg.Text = " Hello Silverlight World! " ;
}
else
{
this .Msg.Text = " 你好, " + UserInputContent ;
}
整个Hello World的开发过程到现在就完成了。单击F5健,在文本输入框里面输入你的名字,可以看到程序运行结果如下:
几点说明:
1,工具箱中的控件只能拖放到XAML代码区域,不能拖放到设计区域,该界面布局带来很多的不方便【WPF应用程序里面有效】;
2,文档大纲的预览和属性框都不可用,估计是Beta版还没有完成吧。
3,元素定位需要放在Canvas里面,具体介绍参见:
http://dotnet.aspx.cc/SilverlightSDK/Silverlight/conceptual/c_Silverlight_positioning.htm
我们今天的关于Silverlight玩转控件和二——Canvas布局的分享就到这里,谢谢您的阅读,如果想了解更多关于canvas – 如何在Silverlight中绘制箭头、My Silverlight系列(10)—— Silverlight中的InkCanvas、Silverlight 2学习教程(九):Silverlight 2 beta2 新控件介绍之 TabControl 控件、Silverlight 2学习教程(二):开发简单的Silverlight 2应用程序的相关信息,可以在本站进行搜索。
本文标签: