人立方关系搜索的silverlight控件外观定制揭秘
2011-09-20 11:35
281 查看
最近微软亚洲研究院的人立方关系搜索新发布了几个Silverlight的应用,包括关系图搜索,六度搜索和新闻时间轴。相信其绚丽的界面效果和赏心悦目的动画给大家留下了深刻印象。这里,我就尝试和大家一起来对这些应用进行揭谜,着重探讨siliverlight中三种定制控件外观的方法:1)在代码里面设置控件的风格这种方法只能对控件的外观做一些简单的,轻量级的修改。比如这个半透明的矩形框:我们只需要在代码里面这样写:<RectangleFill="White"Opacity="0.1"Height="75"Canvas.Left="0"Canvas.Top="1"Margin="0,0,0,100"Width="20000"/>其中Opacity属性就是设置矩形框的透明度,这里设为0.1,使其非常透明。可惜的是,这个矩形框在后来的设计中去掉了L2)把控件的风格写成资源文件很多情况下,上面的方法就够用了。但是有时我们会遇到这样的情况:我们需要给多个控件设置类似的属性。仍然以上面的矩形框为例子,那代码就会是这样:<RectangleFill="White"Opacity="0.1"Height="75"Canvas.Left="0"Canvas.Top="1"Margin="0,0,0,100"Width="2000"/><RectangleFill="White"Opacity="0.2"Height="75"Canvas.Left="0"Canvas.Top="1"Margin="0,0,0,100"Width="2000"/><RectangleFill="White"Opacity="0.3"Height="75"Canvas.Left="0"Canvas.Top="1"Margin="0,0,0,100"Width="2000"/><RectangleFill="White"Opacity="0.4"Height="75"Canvas.Left="0"Canvas.Top="1"Margin="0,0,0,100"Width="2000"/>……有没有简单清晰的做法呢?有的!我们仍然以六度搜索界面中的控件为例子:图中白色的矩形框显示了两个人物之间的关系来源。现在我们来设置其中黄色框中的两个名字的显示属性。它是一个TextBlock控件,代码里面我们这样写:<TextBlockx:Name="textBlock"Text="{BindingPath=TitleB}"Style="{StaticResourceTitleBlock}"/>这个TextBlock的风格指向了名为”TitleBlock”的资源,其定义为:<Stylex:Key="TitleBlock"TargetType="TextBlock"><SetterProperty="FontFamily"Value="MicrosoftYaHei"/><SetterProperty="FontSize"Value="12"/><SetterProperty="VerticalAlignment"Value="Center"/><SetterProperty="HorizontalAlignment"Value="Left"/><SetterProperty="Grid.Row"Value="1"/><SetterProperty="Grid.Column"Value="1"/><SetterProperty="Grid.ColumnSpan"Value="1"/></Style>这样,多个控件可以共享这个名为“TitleBlock”的资源。我们可以通过修改这个资源文件,从而轻易的修改多个控件的外观。3)重写控件的模板有时我们不得不面对复杂一些的情况:请看图中黄色椭圆框中的控件,它们都是Button控件,但是其外观被完全改头换面了。我会选取其中三个控件作为例子在这里谈一谈:3.1箭头按钮这个按钮的外形是个三角形,其定义为:<Buttonx:Name="arrowUp"Canvas.Top="9"Canvas.Left="15"Canvas.ZIndex="99"Style="{StaticResourceArrowUpButton}"Click="ArrayUp_Click"/>它的Style指向了:那么如果想做这个具有人立方特色的圆圈按钮,其步骤就可以分为如下几步:3.2.1把多个Ellipse控件封装到Button控件中<GridHeight="auto"HorizontalAlignment="Center"VerticalAlignment="Center"Width="auto"IsHitTestVisible="True"Background="{x:Null}"><EllipseMargin="0,0,0,0"Stroke="{x:Null}"HorizontalAlignment="Center"VerticalAlignment="Center"Width="{TemplateBindingCircleButtonWidth1}"Height="{TemplateBindingCircleButtonHeight1}"IsHitTestVisible="False"x:Name="ellipse1"Fill="{TemplateBindingEllipse1Fill}"></Ellipse><GridMargin="0,0,0,0"HorizontalAlignment="Center"Width="1024"Height="1024"VerticalAlignment="Center"RenderTransformOrigin="0.5,0.5"x:Name="grid"Opacity="1"Background="{x:Null}"IsHitTestVisible="True"><EllipseFill="{TemplateBindingEllipse2Fill}"Stroke="{TemplateBindingEllipse2Stroke}"Margin="0,0,0,0"Width="{TemplateBindingCircleButtonWidth2}"Height="{TemplateBindingCircleButtonHeight2}"x:Name="ellipse2"RenderTransformOrigin="0.5,0.5"HorizontalAlignment="Center"VerticalAlignment="Center"></Ellipse><EllipseMargin="2,2,2,2"Fill="{TemplateBindingEllipse3Fill}"Width="{TemplateBindingCircleButtonWidth3}"Height="{TemplateBindingCircleButtonHeight3}"x:Name="ellipse3"RenderTransformOrigin="0.5,0.5"HorizontalAlignment="Center"VerticalAlignment="Center"></Ellipse><TextBlockMargin="0,0,0,0"FontFamily="MicrosoftYaHei"FontSize="{TemplateBindingFontSize}"Foreground="#FFFFFFFF"HorizontalAlignment="Center"VerticalAlignment="Center"x:Name="textBlock"Text="{TemplateBindingContent}"RenderTransformOrigin="0.5,0.5"IsHitTestVisible="False"></TextBlock></Grid></Grid>3.2.2注册一些属性,使得我们可以在代码里面动态的设置它们:3.2.3给其中部分Ellipse控件加上合适的storyboard,来处理鼠标的MouseOver事件人立方的silverlight应用里面还有这样的线段按钮,它很细,但是很容易被鼠标点击到,具有很好的用户体验。其制作步骤也是类似的:3.3.1.封装两个Path控件到Button控件中:a)一个用来处理鼠标的Mouseover事件<Pathx:Name="outerPath"Stroke="White"StrokeThickness="10"Data="{TemplateBindingOuterPathData}"Opacity="0"></Path>b)一个用来显示这条线段<Pathx:Name="path"Stroke="White"StrokeThickness="1"Data="{TemplateBindingPathData}"Opacity="{TemplateBindingOpacity}"></Path>3.3.2.注册Path的Data属性http://renlifang.msra.cn/6du.aspx人立方六度连连看(Flash):http://renlifang.msra.cn/6dumap.aspx人立方实时资讯关系图(Silverlight):http://renlifang.msra.cn/news.aspx人立方实时资讯关系图(Flash):http://renlifang.msra.cn/newsMap.aspx
<Stylex:Key="ArrowUpButton"TargetType="Button"> <SetterProperty="Cursor"Value="Hand"></Setter> <SetterProperty="Template"> <Setter.Value> <ControlTemplateTargetType="Button"> <Grid> <VisualStateManager.VisualStateGroups> <VisualStateGroupx:Name="FocusStates"> <VisualStatex:Name="Unfocused"/> <VisualStatex:Name="Focused"/> </VisualStateGroup> <VisualStateGroupx:Name="CommonStates"> <VisualStatex:Name="MouseOver"/> <VisualStatex:Name="Pressed"/> <VisualStatex:Name="Disabled"/> <VisualStatex:Name="Normal"/> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Polygon Points="0,55,010,50,5" Stroke="White" StrokeThickness="0"> <Polygon.Fill> <SolidColorBrushColor="White"Opacity="1"/> </Polygon.Fill> </Polygon> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>我们可以看到,这个控件的“内部”被放入了一个Polygon控件,所以这个箭头按钮会呈现这个Polygon所描绘的三角形。3.2圆圈按钮
///<summary>///Theellipse1fill.///</summary>publicBrushEllipse1Fill{get{return(Brush)base.GetValue(Ellipse1FillProperty);}set{base.SetValue(Ellipse1FillProperty,value);}}///<summary>///Registerproperty.///</summary>publicstaticreadonlyDependencyPropertyEllipse1FillProperty=DependencyProperty.Register("Ellipse1Fill",typeof(Brush),typeof(CircleButton),null);这里我们就注册了名为Ellipse1Fill的属性,于是就可以设置它的值:
<VisualStatex:Name="MouseOver"><Storyboard><DoubleAnimationUsingKeyFramesBeginTime="00:00:00"Duration="00:00:00.0010000"Storyboard.TargetName="ellipse2"Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"><SplineDoubleKeyFrameKeyTime="00:00:00"Value="1.5"/></DoubleAnimationUsingKeyFrames><DoubleAnimationUsingKeyFramesBeginTime="00:00:00"Duration="00:00:00.0010000"Storyboard.TargetName="ellipse2"Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"><SplineDoubleKeyFrameKeyTime="00:00:00"Value="1.5"/></DoubleAnimationUsingKeyFrames><DoubleAnimationUsingKeyFramesBeginTime="00:00:00"Duration="00:00:00.0010000"Storyboard.TargetName="ellipse3"Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"><SplineDoubleKeyFrameKeyTime="00:00:00"Value="1.5"/></DoubleAnimationUsingKeyFrames><DoubleAnimationUsingKeyFramesBeginTime="00:00:00"Duration="00:00:00.0010000"Storyboard.TargetName="ellipse3"Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"><SplineDoubleKeyFrameKeyTime="00:00:00"Value="1.5"/></DoubleAnimationUsingKeyFrames><DoubleAnimationUsingKeyFramesBeginTime="00:00:00"Duration="00:00:00.0010000"Storyboard.TargetName="textBlock"Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"><SplineDoubleKeyFrameKeyTime="00:00:00"Value="1.5"/></DoubleAnimationUsingKeyFrames><DoubleAnimationUsingKeyFramesBeginTime="00:00:00"Duration="00:00:00.0010000"Storyboard.TargetName="textBlock"Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"><SplineDoubleKeyFrameKeyTime="00:00:00"Value="1.5"/></DoubleAnimationUsingKeyFrames></Storyboard></VisualState>这样,这个具有人立方特色的圆圈按钮就完成了。3.3线段按钮
publicGeometryPathData{get{return(Geometry)base.GetValue(PathDataProperty);}set{base.SetValue(PathDataProperty,value);}}publicstaticreadonlyDependencyPropertyPathDataProperty=DependencyProperty.Register("PathData",typeof(Geometry),typeof(PathButton),null);3.3.3.Path控件的Data属性设置为特殊的贝赛尔曲线,使得整个关系图看起来更具有立体感。this.PathData=CreatePathData();privatePathGeometryCreatePathData(){PathGeometrypathGeometry=newPathGeometry();PathFigurepathFigure=newPathFigure();pathFigure.StartPoint=leftPoint;pathGeometry.Figures.Add(pathFigure);PointmidPoint=To2D.getPoint(leftPoint,rightPoint,centerPoint);QuadraticBezierSegmentarcs=newQuadraticBezierSegment();arcs.Point1=midPoint;arcs.Point2=rightPoint;pathFigure.Segments.Add(arcs);returnpathGeometry;}3.3.4.加入对应的storyboardDoubleAnimationopacity=newDoubleAnimation();opacity.From=0;opacity.To=endOpacity;opacity.Duration=newDuration(TimeSpan.FromSeconds(1));Storyboardstory=newStoryboard();story.Children.Add(opacity);Storyboard.SetTarget(opacity,this);Storyboard.SetTargetProperty(opacity,newPropertyPath("(UIElement.Opacity)"));story.BeginTime=TimeSpan.FromSeconds(beginTime);story.Completed+=newEventHandler(AppearStory_Completed);story.Begin();使得当鼠标hover到线段按钮上时,整条线段变亮。快速链接:人立方六度连连看(Silverlight):
相关文章推荐
- 定制Silverlight 2控件外观比较好的资料
- Xpage中对定制控件在设计视图下外观的定制
- Silverlight 中文教程第七部分: 使用控件模板定制控件的观感
- Silverlight教程第七部分: 使用控件模板定制控件的观感
- 【Silverlight】Bing Maps开发应用与技巧六:使用样式美化图钉(Pushpin)控件的ToolTip外观
- 【Silverlight】Bing Maps开发应用与技巧六:使用样式美化图钉(Pushpin)控件的ToolTip外观
- Silverlight教程第七部分: 使用控件模板定制控件的观感
- WTL初步:定制控件外观
- Silverlight教程第七部分: 使用控件模板定制控件的观感
- SilverLight 封装控件外观
- UIAppearance定制控件的默认外观
- 定制ObjectDataSource控件的设计视图外观
- 【Silverlight】Bing Maps开发应用与技巧六:使用样式美化图钉(Pushpin)控件的ToolTip外观 推荐
- Silverlight教程第七部分: 使用控件模板定制控件的观感
- Silverlight教程第七部分: 使用控件模板定制控件的观感
- Silverlight教程第七部分: 使用控件模板定制控件的观感
- Silverlight教程第七部分: 使用控件模板定制控件的观感
- (译)Silverlight教程第七部分: 使用控件模板定制控件的观感
- 使用appearance proxy定制控件的默认外观(详解)
- Silverlight教程第七部分: 使用控件模板定制控件的观感