Expression Blend 4例程序ColorSwatchSL详解

来源:互联网 发布:淘宝制作彩铃能上传吗 编辑:程序博客网 时间:2024/05/17 04:07

本人初学WPF,这个例程也是自己一点点啃一点点弄懂的,本文从每个细节分析该例程,本人新建一个工程仿写该程序,记录自己的学习经历,也希望与大家分享。

本文主要分析该例程的结构、特效是怎么实现的、如何在blend中操作来实现这些特效,基础概念请自行查阅相关资料。

一、程序结构

从图中可以清楚的了解工程的树结构,实现特效的主要有两个,listBoxSwatches 和detailsBox,其他都是一些静态的布局文件,很好理解。

二、listBoxSwatches特效


listBoxSwatches是一个ListBox控件,我们在该工程中新建一个画布,来一步步看如何做到这种环状卡片效果的。

首先,画一个boarder,在这个boarder中添加一个LixtBox,将"数据"里面的SwatchCollection托到该ListBox中,这一步操作实现了数据binding,

效果如图,


这就是一个普通的ListBox,可以看出,有三个元素表示颜色,一个元素表示颜色的名称

第二步,给每个元素添加一个自定义的样式,我们称之为Style,

右键ListBox->编辑其他模板->编辑项目的生成容器,由于现在没有任何Style,因此我们选择创建一个空项,名字叫My_ListBoxItemStyle。

用Fill画四个矩形,再加一个Text


第三步,数据binding,我们想让三个Fill分别显示表格中给出的三种颜色,TextBox显示颜色名,在属性设置中将数据绑定,完成后再看ListBox的效果图


第四步,当鼠标经过其中的元素时,有一个放大效果,要实现这个效果,我们用到了Blend里面的状态和Storyboard。

有关控件状态的意思可以查阅相关资料

还是在编辑项目的生成容器界面里,选择状态窗口,可以看到有个MouseOver一项,选中后主窗口会由红线包住,并提示MouseOver状态记录已打开,这时就进入了Storyboard模式,相当于在这个界面改变了容器的样子例如大小位置,当鼠标移动的元素上方时,就会发生此变化。我们将元素的大小设置的大一些。

现在返回到UserControl,运行程序,当鼠标经过元素项时,该元素项就会放大,鼠标移开后还原。


下面我们讲如何将这些元素按环形排列:

我们可以通过更改ListBox的布局,来实现这一效果,

右键ListBox->编辑其他模板->编辑项的布局,我们可以发现例程应用了一个布局资源ColorsItemsPanelTemplete文件。 

但是点了编辑当前模板之后,我们并不能看出这个环形布局是如何实现的。

我们查看XAML文件可以发现

<ItemsPanelTemplate x:Key="Colors_ItemsPanelTemplate">
<local:CircularPanel Align="Center" Radius="146" Width="500" Height="500" IsAnimated="True" AngleItem="17" InitialAngle="90" AnimationDuration="50"/>
</ItemsPanelTemplate>

这行代码指定了该ListBox的布局文件为local:CircularPanel类(local在文件开头有定义,xmlns:local="clr-namespace:ColorSwatchSL" ,表示namespace:ColorSwatchSL这个命名空间),这样我们明白,该布局是由工程中CircularPanel.cs这个文件中叫做CircularPanel 的类来规定的。

CircularPanel 类继承了Panel类,重写了MeasureOverride和ArrangeOverride两个函数,理解这个类是如何改变布局的对新手来说比较复杂,我们从最简单的开始。

通过查阅MSDN的Panel类,里面有一个例程,该例程是让所有的元素都在一个点重合,为了让视觉效果更加直观,我们更改一个地方,使每个元素重叠排列,代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;


namespace ColorSwatchSL
{
public class PlotPanel : Panel
{
// Default public constructor
public PlotPanel()
: base()
{
}

// Override the default Measure method of Panel
protected override Size MeasureOverride(Size availableSize)
{
Size panelDesiredSize = new Size();

// In our example, we just have one child. 
// Report that our panel requires just the size of its only child.
foreach (UIElement child in this.Children)
{
child.Measure(availableSize);
panelDesiredSize = child.DesiredSize;
}

return panelDesiredSize ;
}
protected override Size ArrangeOverride(Size finalSize)
{
int i=0;
foreach (UIElement child in this.Children)
{
double x = 50+i*10;
double y = 50+i*15;
i++;
child.Arrange(new Rect(new Point(x, y), child.DesiredSize));
}
return finalSize; // Returns the final Arranged size
}
}
}

元素位置由

double x = 50+i*10;
double y = 50+i*15;

两行代码决定。效果如图

关于如何重写Panel类使之按环形排列再单独讨论。

三、detailsBox特效

当我们点击ListBox其中第一个元素时,有一个框弹出来,下面我们来实现这个特效,使用GoToStateAction控件。

先把GoToStateAction添加给ListBox,在属性设置中,将触发条件设置为SelectionChanged,将GoToStateAction指向我们下面创建的状态My_State

在状态窗口中,添加一个状态组My_States

添加一新状态My_State,给这个状态添加一个过渡,在初始态画一个Fill,大小设置为0,然后在My_State状态将这个Fill变大,这样就有一个从无到有的变化过程

现在的效果是,每点击ListBox的一个元素,就会弹出一个Fill,但是Fill的颜色固定,如果我们想让点击不同的元素,Fill的颜色为我们点击的元素颜色,那么就需要用到绑定功能。

data绑定分为数据绑定和元素属性绑定。数据绑定我们之前用过,现在使用的是元素属性绑定

我们将DataContext绑定在Border上,绑定ListBox的SelectedItem属性。

<Border x:Name="border" BorderThickness="1" HorizontalAlignment="Right" Margin="0,155,104,0" Width="0" Height="0" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" Background="{x:Null}" DataContext="{Binding SelectedItem, ElementName=listBox}">

<Border.RenderTransform>
<CompositeTransform/>
</Border.RenderTransform>
<Rectangle x:Name="rectangle" Fill="{Binding Color1}" Margin="21,23,0,0" HorizontalAlignment="Left" Height="30" VerticalAlignment="Top" Width="41" RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<CompositeTransform/>
</Rectangle.RenderTransform>
</Rectangle>
</Border>

从代码中可以看出Fill绑定的颜色为 Color1,Boarder绑定了元素属性DataContext="{Binding SelectedItem, ElementName=listBox},这样该Fill的颜色由选定的ListBox中元素的Color1决定。

当然我们也可以在Fill中同时绑定DataContext和Fill,代码如下。效果同上

<Border x:Name="border" BorderThickness="1" HorizontalAlignment="Right" Margin="0,155,104,0" Width="0" Height="0" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" Background="{x:Null}" >
<Border.RenderTransform>
<CompositeTransform/>
</Border.RenderTransform>
<Rectangle x:Name="rectangle" Fill="{Binding Color1}" Margin="21,23,0,0" HorizontalAlignment="Left" Height="30" VerticalAlignment="Top" Width="41" RenderTransformOrigin="0.5,0.5" DataContext="{Binding SelectedItem, ElementName=listBox}">
<Rectangle.RenderTransform>
<CompositeTransform/>
</Rectangle.RenderTransform>
</Rectangle>
</Border>

0 0
原创粉丝点击