本部分主要介绍用户控件,个人认为SilverLight用户控件分为两种:组合控件和自定义控件。
组合控件:把几种现成的控件在不改变原有属性的情况下在控件内部对各自的属性、事件进行处理,其实每一个xaml文件就是一个用户控件。
自定义控件:把几种原有的基本控件结合成自已想要的一种形状,并对组合成后的控件提供属性、事件,从而可以在外部引用控件时对相应的属性、事件进行处理。
1、创建一个组合控件
在app.xaml中建立样式与模板(对于样式与模板微软提供的一个Expression Blend 2可以更好的开发控件的样式,这里先不对如何使用Express Blend做介绍,我将在以后对Express Blend做一个专题介绍),代码如下:
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="DetailControl.App"
>
<Application.Resources>
<Style TargetType="TextBlock" x:Key="TextBlockStyle">
<Setter Property="Foreground" Value="Coral"/>
<Setter Property="FontSize" Value="28"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
<Style x:Key="CloseButton" TargetType="Button"/>
<ControlTemplate x:Key="CloseButtonTemplate" TargetType="Button">
<Grid Width="23" Height="20" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0">
<Rectangle HorizontalAlignment="Stretch" Margin="0,0,0,0" RadiusX="5" RadiusY="5" StrokeThickness="3">
<Rectangle.Stroke>
<LinearGradientBrush EndPoint="0.0390000008046627,0.800999999046326" StartPoint="0.912999987602234,0.216999992728233">
<GradientStop Color="#FF000000"/>
<GradientStop Color="#FF0F56B6" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Stroke>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.477999985218048,-1.04299998283386">
<GradientStop Color="#FF000000"/>
<GradientStop Color="#FFB1D2DD" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock Text="X" TextWrapping="Wrap" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" Cursor="Hand" TextAlignment="Center" FontWeight="Bold">
<TextBlock.Foreground>
<LinearGradientBrush EndPoint="0.488999992609024,0.996999979019165" StartPoint="0.460999995470047,0.223000004887581">
<GradientStop Color="#FF000000" Offset="0"/>
<GradientStop Color="#FFEB1757" Offset="1"/>
<GradientStop Color="#FF9D0F3A" Offset="1"/>
</LinearGradientBrush>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</ControlTemplate>
</Application.Resources>
</Application>
在DetailInfo.xaml中建立用户控件,代码如下:
<UserControl x:Class="DetailControl.DetailInfo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot" Background="White">
<Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Opacity="0.3" Fill="Gray"/>
<Canvas SizeChanged="Canvas_SizeChanged">
<Border x:Name="borderBookInfo" CornerRadius="20" Background="LightCyan" Width="450" Height="150"
MouseLeftButtonDown="borderBookInfo_MouseLeftButtonDown" MouseMove="borderBookInfo_MouseMove"
MouseLeftButtonUp="borderBookInfo_MouseLeftButtonUp">
<StackPanel Orientation="Horizontal" Margin="10,5,5,5">
<StackPanel Width="150" VerticalAlignment="Center">
<Image Source="{Binding ImgPath}"></Image>
</StackPanel>
<StackPanel Width="258" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock Text=" 编号:"></TextBlock>
<TextBlock Text="{Binding BookId}" ></TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text=" 标题:" ></TextBlock>
<TextBlock Text="{Binding Title}" ></TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text=" 价格:" ></TextBlock>
<TextBlock Text="{Binding Price}" ></TextBlock>
</StackPanel>
</StackPanel>
<StackPanel>
<Button x:Name="btnClose" Content="Close" Style="{StaticResource CloseButton}" Click="btnClose_Click"
Template="{StaticResource CloseButtonTemplate}" ToolTipService.ToolTip="Close"/>
</StackPanel>
</StackPanel>
</Border>
</Canvas>
</Grid>
</UserControl>
using System.Windows.Interop;
namespace DetailControl
{
public partial class DetailInfo : UserControl
{
bool bIsMoving = false; //是否移动
Point oldPosition; //鼠标原来的位置
public DetailInfo()
{
InitializeComponent();
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
Visibility = Visibility.Collapsed; //设置本控件隐藏
}
private void borderBookInfo_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement fElement = sender as FrameworkElement; //获取鼠标点击的元素
if (null != fElement)
{
oldPosition = e.GetPosition(this); //获取元素的位置
bIsMoving = true; //设置鼠标正在移动
fElement.CaptureMouse(); //当前元素获取鼠标
fElement.Cursor = Cursors.Hand; //设置元素鼠标的形状
}
}
private void borderBookInfo_MouseMove(object sender, MouseEventArgs e)
{
FrameworkElement fElement = sender as FrameworkElement; //获取鼠标移动的元素
if (null != fElement && bIsMoving)
{
Point curPosition = e.GetPosition(this); //获取元素移动到的位置
Double pY = curPosition.Y - oldPosition.Y; //获取元素现在的位置与原来位置鼠标的差值
Double pX = curPosition.X - oldPosition.X;
Double canvasY = pY + Canvas.GetTop(fElement); //获取元素在Canvas中原来的位置,并加上元素移动的位置
Double canvasX = pX + Canvas.GetLeft(fElement);
Canvas.SetLeft(fElement, canvasX); //设置元素在Canvas中当前的位置
Canvas.SetTop(fElement, canvasY);
oldPosition = e.GetPosition(this); //把当前位置设置为原始位置
}
}
private void borderBookInfo_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
FrameworkElement fElement = sender as FrameworkElement;
if (null != fElement)
{
fElement.ReleaseMouseCapture(); //当前元素释放鼠标
bIsMoving = false; //设置控件状态为静止
fElement.Cursor = null; //元素释放鼠标
}
}
private void Canvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
Content BrowserHost = new Content(); //创建浏览器宿主对象
double x = BrowserHost.ActualWidth; //获取当前页面的宽度与高度
double y = BrowserHost.ActualHeight;
//设置控件为页面正中间显示如下
Canvas.SetLeft(borderBookInfo, (BrowserHost.ActualWidth - borderBookInfo.Width) / 2);
Canvas.SetTop(borderBookInfo, (BrowserHost.ActualHeight - borderBookInfo.Height) / 2);
}
}
}
为了引用DetailInfo用户控件,需要在Page.xaml中声名:xmlns:custom="clr-namespace:DetailControl",xaml代码如下:
<UserControl xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="DetailControl.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:DetailControl">
<Grid x:Name="LayoutRoot">
<my:DataGrid x:Name="dgTest" AutoGenerateColumns="False" Width="Auto" Margin="0,5,0,0" Height="Auto"
HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" GridLinesVisibility="All"
SelectionChanged="dgTest_SelectionChanged">
<my:DataGrid.Columns>
<my:DataGridTextColumn Header="标题" Binding="{Binding Title}"/>
<my:DataGridTextColumn Header="价格" Binding="{Binding Price}"/>
<my:DataGridCheckBoxColumn Header="是否有货" Binding="{Binding IsOOS}"/>
<my:DataGridTemplateColumn Header="出版日期">
<my:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding PublishDate}"></TextBlock>
</DataTemplate>
</my:DataGridTemplateColumn.CellTemplate>
<my:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<basics:DatePicker SelectedDate="{Binding PublishDate, Mode=TwoWay}"></basics:DatePicker>
</DataTemplate>
</my:DataGridTemplateColumn.CellEditingTemplate>
</my:DataGridTemplateColumn>
</my:DataGrid.Columns>
</my:DataGrid>
<custom:DetailInfo x:Name="DetailInfo" Visibility="Collapsed">
</custom:DetailInfo>
</Grid>
</UserControl>
public partial class Page : UserControl
{
bool bIsFirstLoad = false;
public Page()
{
InitializeComponent();
BindDataGrid();
}
private void BindDataGrid()
{
List<Book> list = new List<Book>();
for (int i = 0; i < 10; ++i)
{
list.Add(new Book
{
BookId = i,
Title = "SilverLight 2.0 高级编程" + i.ToString(),
Price = 28 + i,
PublishDate = DateTime.Now.AddDays(i),
IsOOS = 0 == (i % 2),
ImgPath = "logo.jpg"
});
}
dgTest.ItemsSource = list;
bIsFirstLoad = true;
}
private void dgTest_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!bIsFirstLoad)
{
if (null != dgTest.SelectedItem)
{
DetailInfo.DataContext = dgTest.SelectedItem;
DetailInfo.Visibility = Visibility.Visible;
}
}
else
{
bIsFirstLoad = false;
}
}
}
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public DateTime PublishDate { get; set; }
public bool IsOOS { get; set; }
public string ImgPath { get; set; }
}
运行效果如下:
2、创建一个自定义控件
添加一个MyButton.xmal文件,清空里面的代码,添加代码如下:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Custom="clr-namespace:CustomControl;assembly=CustomControl">
<Style TargetType="Custom:MyButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Custom:MyButton">
<Grid>
<ContentPresenter
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
public event RoutedEventHandler Click;
public MyButton()
{
MouseLeftButtonDown += new MouseButtonEventHandler(MyButton_MouseLeftButtonDown);
}
void MyButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (Click != null)
{
Click(this, new RoutedEventArgs());
}
}
在Page.xaml文件中引用Mybutton控件,代码如下:
<UserControl x:Class="CustomControl.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Custom="clr-namespace:CustomControl">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Margin="0,30,0,0">
<Custom:MyButton Content="I am a Button" FontSize="28" Click="MyButton_Click" Foreground="Red" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
</UserControl>
private void MyButton_Click(object sender, RoutedEventArgs e)
{
System.Windows.Browser.HtmlPage.Window.Alert("I am a Button!");
}
运行效果如下:
综述:本部分主要介绍了用户控件,下一讲我们将介绍第二大部分,动画部分第一讲:使用Expression Blend 2。