原文链接:http://www.cnblogs.com/Wade-/archive/2012/06/23/2559426.html
这是一个用Sliverlight实现的一个测试程序“测试你古代的名字”,内容来源于互联网。
这是程序实现效果:
在输入姓名首字母和生日的月份以及选择性别后,再按查询键,实现测试程序过程。
本程序中的数据是利用XML文件储存数据的,应此需要用到System.Xml和System.Xml.Linq两个命名空间。在这里我把关于XML文件的操作放在XMLReader类中:
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Xml; using System.Xml.Linq; namespace SilverlightApplication2 { /// <summary> /// XML的读取函数 /// </summary> public class XMLReader { public enum Sex:int { boy=1, girl=2 } private Uri uri; private XNode nameNode; private XNode girlDayNode; private XNode girlMonthNode; private XNode boyDayNode; private XNode boyMonthNode; /// <summary> /// 实例化一个XMLReader类 /// </summary> /// <param name="url">xml文件路径</param> public XMLReader(Uri url) { uri = url; XDocument xdoc=new XDocument(); xdoc= XDocument.Load(uri.ToString()); nameNode = xdoc.Root.FirstNode; girlDayNode = ((XElement)(xdoc.Root.FirstNode.NextNode)).FirstNode; girlMonthNode = ((XElement)(xdoc.Root.FirstNode.NextNode)).FirstNode.NextNode; boyDayNode = ((XElement)(xdoc.Root.LastNode)).FirstNode; boyMonthNode = ((XElement)(xdoc.Root.LastNode)).FirstNode.NextNode; } /// <summary> /// 获取指定日期所代表的名字 /// </summary> /// <param name="sex">性别(男孩,女孩)</param> /// <param name="day">日期</param> /// <returns>指定日期所代表的名</returns> public string GetDayText(Sex sex,string day) { string value=""; if(sex==Sex.boy) { XElement xe=(XElement) boyDayNode; foreach (XElement name in xe.Elements()) //循环查找XElement { if (name.FirstAttribute.Value == day)//判断其FirstAttribute是否为指定值 { value = name.Value;//赋值 break; //跳出循环 } } } else if (sex == Sex.girl) { XElement xe = (XElement)girlDayNode; foreach (XElement name in xe.Elements()) { if (name.FirstAttribute.Value == day) { value = name.Value; break; } } } return value; } /// <summary> /// 获取指定月份所代表的名字 /// </summary> /// <param name="sex">性别(男孩,女孩)</param> /// <param name="day">月份</param> /// <returns>姓首字母</returns> public string GetMonthText(Sex sex, string month) { string value = ""; if (sex == Sex.boy) { XElement xe = (XElement)boyMonthNode; foreach (XElement name in xe.Elements()) { if (name.FirstAttribute.Value == month) { value = name.Value; } } } else if (sex == Sex.girl) { XElement xe = (XElement)girlMonthNode; foreach (XElement name in xe.Elements()) { if (name.FirstAttribute.Value == month) { value = name.Value; } } } return value; } /// <summary> /// 获取指定姓首字母所代表的姓 /// </summary> /// <param name="name">姓首字母</param> /// <returns>指定姓首字母所代表的姓</returns> public string GetNameText(string name) { string value = ""; XElement xe = (XElement)nameNode; foreach (XElement ename in xe.Elements()) { if (ename.FirstAttribute.Value == name) { value = ename.Value; } } return value; } } }
XDocument 类代表一个XML文档,用XDocument 的静态方法Load加载一个xml文档,然后用root属性获取根节点,用FirstNode获取根节点中的第一个节点,而用NextNode可以获取该节点的后一个节点。
XElement 类表示一个 XML 元素。通过XElement 类的Elements属性获得每个子节点的XElement。
接下来该要写界面了,Grid的布局,背景是用渐变画刷LinearGradientBrush。这里直列出xaml文件的内容:
<navigation:Page xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SilverlightApplication2.Page1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" d:DesignWidth="640" d:DesignHeight="480" Title="测试你古代的名字"> <Grid x:Name="LayoutRoot"> <Grid.Background> <LinearGradientBrush> <GradientStop Offset="0.3" Color="Green"></GradientStop> <GradientStop Offset="0.6" Color="Beige"></GradientStop> <GradientStop Offset="1" Color="Azure"></GradientStop> </LinearGradientBrush> </Grid.Background> <Grid VerticalAlignment="Center"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions> <TextBlock Style="{StaticResource BigFont}" HorizontalAlignment="Center" Margin="20,20,20,20" Text="测试你古代的名字" x:Name="toptitle" MouseMove="toptitle_MouseMove_1" MouseLeave="toptitle_MouseLeave_1"> <TextBlock.RenderTransform> <TranslateTransform X="0" x:Name="tst"></TranslateTransform> </TextBlock.RenderTransform> </TextBlock> <Grid Grid.Row="1"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" HorizontalAlignment="Center"> <TextBlock Margin="20,10,20,20" Text="输入你姓名的第一个字母:" RenderTransformOrigin="0.5,0.5"> <TextBlock.RenderTransform> <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleY="-1" x:Name="dnf1"></ScaleTransform> </TextBlock.RenderTransform> </TextBlock> <TextBox Margin="20,10,20,20" Width="100" Name="nametext" MaxLength="1" MouseEnter="nametext_MouseEnter_1" MouseLeave="nametext_MouseLeave_1" TextChanged="nametext_TextChanged_1"> </TextBox> </StackPanel> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Stretch" Grid.Row="1"> <TextBlock Margin="59,10,55,20" Text="输入你的生日" > <TextBlock.RenderTransform> <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleY="-1" x:Name="dnf2"/> </TextBlock.RenderTransform> </TextBlock> <ComboBox Name="cb_month" Margin="50,10,20,20" SelectionChanged="ComboBox_SelectionChanged_1" Loaded="ComboBox_Loaded_1" MinWidth="40" MouseEnter="nametext_MouseEnter_1" MouseLeave="nametext_MouseLeave_1"> <ComboBoxItem/> </ComboBox> <TextBlock Margin="0,10,0,20"> <Run Text="月"/> </TextBlock> <ComboBox Name="cb_day" Margin="20,10,20,20" SelectionChanged="ComboBox_SelectionChanged_2" MinWidth="40" MouseEnter="nametext_MouseEnter_1" MouseLeave="nametext_MouseLeave_1" > <ComboBoxItem/> </ComboBox> <TextBlock Margin="0,10,0,20"> <Run Text="日"/> </TextBlock> <!-- <TextBox Margin="20,10,20,20" Width="100" Name="birthdaytext" MouseEnter="nametext_MouseEnter_1" MouseLeave="nametext_MouseLeave_1"></TextBox>--> </StackPanel> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Stretch" Grid.Row="2"> <TextBlock Margin="20,10,75,20" Text="选择你的性别:"> <TextBlock.RenderTransform> <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleY="-1" x:Name="dnf3"></ScaleTransform> </TextBlock.RenderTransform> </TextBlock> <ComboBox SelectedIndex="0" Margin="20,10,20,20" Width="100" Name="sextext" MouseEnter="nametext_MouseEnter_1" MouseLeave="nametext_MouseLeave_1"> <ComboBoxItem Tag="1" > 男 </ComboBoxItem> <ComboBoxItem Tag="2"> 女 </ComboBoxItem> </ComboBox> </StackPanel> <Button Content="查询" Margin="20,10,20,20" Grid.Row="3" Width="50" Click="Button_Click_1" Height="22" VerticalAlignment="Bottom"></Button> </Grid> <StackPanel Grid.Row="2"> <TextBlock Style="{StaticResource BigFont}" Text="你的古代名字是。。。。。。。" Name="bottomtitle" Opacity="0"> </TextBlock> <StackPanel RenderTransformOrigin="0.5,0.5"> <StackPanel.RenderTransform> <TranslateTransform X="-500" x:Name="s_tst"></TranslateTransform> </StackPanel.RenderTransform> <TextBlock Style="{StaticResource BigFont}" HorizontalAlignment="Center" Margin="0,20,0,20" RenderTransformOrigin="0.5,0.5" Name="s_result" MouseMove="s_result_MouseMove_1" MouseLeave="s_result_MouseLeave_1"> <TextBlock.RenderTransform> <RotateTransform CenterX="0.5" CenterY="0.5" Angle="0" x:Name="s_angle"></RotateTransform> </TextBlock.RenderTransform> </TextBlock> </StackPanel> </StackPanel> </Grid> </Grid> </navigation:Page>
然后,就要编写查询按钮的Click事件,该事件中先判断了以上输入是否符合规范,然后调用自定应的StartQuery方法。
/// <summary> /// 判断输入是否正确 /// </summary> /// <param name="achar">输入的字符</param> /// <returns></returns> private bool IsNameTrue( string achar,out string schar) { if (achar != "") { char cchar = Convert.ToChar(achar); if ((cchar >= 65 && cchar <= 90) || (cchar >= 97 && cchar <= 122)) { schar = achar.ToUpper(); return true; } else { schar = achar.ToUpper(); return false; } } else { schar = ""; return false; } } private void Button_Click_1(object sender, RoutedEventArgs e) { DateTime date = new DateTime(); string birthdaytext = GetBirthdayText(); if (birthdaytext != "") { date = DateTime.Parse(birthdaytext); } string firstnamechar=""; firstnamechar=nametext.Text; if (!IsNameTrue(firstnamechar, out firstnamechar)) { MessageBox.Show("您输入的名字首字母不符合规范!!"); return; } else if (birthdaytext == "") { MessageBox.Show("请输入日期!!"); return; } XMLReader.Sex sex =(XMLReader.Sex)Convert.ToInt32(((ComboBoxItem)sextext.SelectedItem).Tag); StartQuery(date, firstnamechar,sex); } /// <summary> /// 获取将要判断的日期 /// </summary> /// <returns></returns> private string GetBirthdayText() { string monthtext=""; string daytext=""; if ((ComboBoxItem)cb_month.SelectedValue != null || (ComboBoxItem)cb_day.SelectedValue != null) { monthtext = ((ComboBoxItem)cb_month.SelectedValue).Content.ToString(); daytext = ((ComboBoxItem)cb_day.SelectedValue).Content.ToString(); } if (monthtext != "" && daytext != "") { return monthtext + "." + daytext; } else { return ""; } } /// <summary> /// 开始根据用户输入的数据查询 /// </summary> /// <param name="date"></param> /// <param name="firstnamechar"></param> /// <param name="sex"></param> private void StartQuery(DateTime date, string firstnamechar,XMLReader.Sex sex) { string month = date.Month.ToString(); string day = date.Day.ToString(); string name = firstnamechar; string result= GetName(month, day, name,sex);//调用自定义的GetName方法获得结果 StartShowResult(result); } private void StartShowResult(string result) { SetOpcAni(bottomtitle,1,new PropertyPath("Opacity"),1); SetTstAni(s_tst,0,new PropertyPath("(X)"),2); s_result.Text = result; } /// <summary> /// 根据用户输入的进行数据查询,并组合字符串 /// </summary> /// <param name="month">日期所代表的名</param> /// <param name="day">月份所代表的名</param> /// <param name="name">姓首字母所代表的姓</param> /// <param name="sex">性别</param> /// <returns>组合后的字符串</returns> private string GetName(string month, string day, string name,XMLReader.Sex sex) { XMLReader xmls = new XMLReader(new Uri("XMLFile1.xml", UriKind.Relative)); string dayText= xmls.GetDayText(sex, day);//获取日期所代表的名 string monthText = xmls.GetMonthText(sex, month);//获取月份所代表的名 string nameText = xmls.GetNameText(name);//获取姓首字母所代表的姓 string value = nameText + monthText + dayText;//组合在一起 return value; }
最后,为了美观些,加了一点点动画效果,通过动画使ScaleTransform中的ScaleY属性值改变,从而使TextBlock标签翻转,而大部分动画是在MouseEnter和MouseLeave事件中处理,配合以上的xaml查看:
private void nametext_MouseEnter_1(object sender, MouseEventArgs e) { Storyboard story = new Storyboard(); DoubleAnimation an = new DoubleAnimation(); an.To = 1; an.Duration = TimeSpan.FromSeconds(1); if (sender.GetType() == typeof(System.Windows.Controls.TextBox)) { TextBox textbox = sender as TextBox; if (textbox.Name == "nametext") { Storyboard.SetTarget(an, dnf1); } } else if(sender.GetType() == typeof(System.Windows.Controls.ComboBox)) { ComboBox combobox = sender as ComboBox; if (combobox.Name == " sextext") { Storyboard.SetTarget(an, dnf3); } else { Storyboard.SetTarget(an, dnf2); } } Storyboard.SetTargetProperty(an,new PropertyPath("(ScaleY)")); story.Children.Add(an); story.Begin(); } private void nametext_MouseLeave_1(object sender, MouseEventArgs e) { Storyboard story = new Storyboard(); DoubleAnimation an = new DoubleAnimation(); an.To = -1; an.Duration = TimeSpan.FromSeconds(1); if (sender.GetType() == typeof(System.Windows.Controls.TextBox)) { TextBox textbox = sender as TextBox; if (textbox.Name == "nametext") { Storyboard.SetTarget(an, dnf1); } } else if (sender.GetType() == typeof(System.Windows.Controls.ComboBox)) { ComboBox combobox = sender as ComboBox; if (combobox.Name == " sextext") { Storyboard.SetTarget(an, dnf3); } else { Storyboard.SetTarget(an, dnf2); } } Storyboard.SetTargetProperty(an, new PropertyPath("(ScaleY)")); story.Children.Add(an); story.Begin(); } private void toptitle_MouseMove_1(object sender, MouseEventArgs e) { SetTstAni(tst, 50, new PropertyPath("(X)"),1); } private void toptitle_MouseLeave_1(object sender, MouseEventArgs e) { SetTstAni(tst, 0, new PropertyPath("(X)"),1); } /// <summary> /// 设置关于TranslateTransform的动画 /// </summary> /// <param name="ang">TranslateTransform对象实例</param> /// <param name="to">通过动画到达的值</param> /// <param name="pp">所需的依赖项</param> /// <param name="time">时间(秒)</param> private void SetTstAni(TranslateTransform tst, double to, PropertyPath pp, double time) { Storyboard story = new Storyboard(); DoubleAnimation da = new DoubleAnimation(); da.To = to; da.Duration = TimeSpan.FromSeconds(time); Storyboard.SetTarget(da, tst); Storyboard.SetTargetProperty(da, pp); story.Children.Add(da); story.Begin(); } private void SetOpcAni(TextBlock text, double to, PropertyPath pp, double time) { Storyboard story = new Storyboard(); DoubleAnimation da = new DoubleAnimation(); da.To = to; da.Duration = TimeSpan.FromSeconds(time); Storyboard.SetTarget(da, text); Storyboard.SetTargetProperty(da, pp); story.Children.Add(da); story.Begin(); } private void s_result_MouseMove_1(object sender, MouseEventArgs e) { SetAngAni(s_angle,90,new PropertyPath("(Angle)"),1); } /// <summary> /// 设置关于RotateTransform的动画 /// </summary> /// <param name="ang">RotateTransform对象实例</param> /// <param name="to">通过动画到达的值</param> /// <param name="pp">所需的依赖项</param> /// <param name="time">时间(秒)</param> private void SetAngAni(RotateTransform ang, double to, PropertyPath pp,double time) { Storyboard story = new Storyboard(); DoubleAnimation da = new DoubleAnimation(); da.To = to; da.Duration = TimeSpan.FromSeconds(time); Storyboard.SetTarget(da, ang); Storyboard.SetTargetProperty(da, pp); story.Children.Add(da); story.Begin(); } private void s_result_MouseLeave_1(object sender, MouseEventArgs e) { SetAngAni(s_angle, 0, new PropertyPath("(Angle)"), 0.5); }
一个测试小程序就这么实现了,以下是在线测试界面和源码下载地址: