原文:WPF Toolkit AutoCompleteBox 实体类绑定 关键字自定义关联搜索匹配

WPF Toolkit AutoCompleteBox 实体类绑定 关键字自定义关联搜索匹配

网上的例子都是零散的   翻阅了 很多篇文章后 再根据 自己项目的实际需求  整理出一个完整的 应用例子

汉字首字母全文匹配

提取绑定实体类相应的ID值

XAML

<Window
x:Class="WpfApp3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp3"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Grid>
<controls:AutoCompleteBox
Name="autoCompleteBox1"
Width="278"
Margin="0,24,0,345"
HorizontalAlignment="Left"
ItemsSource="{Binding}">
<controls:AutoCompleteBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</controls:AutoCompleteBox.ItemTemplate>
</controls:AutoCompleteBox>
<Button
Name="button1"
Width="75"
Height="23"
Margin="92,126,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="button1_Click"
Content="Button" />
</Grid>
</Window>

C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using Utility; namespace WpfApp3
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
/// <summary>
/// 构造函数
/// </summary>
public MainWindow()
{
InitializeComponent();
this.Loaded += Window_Loaded;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
List<CityEntity> cityEntity = new List<CityEntity>() {
new CityEntity(,"北京",""),
new CityEntity(,"上海",""),
new CityEntity(,"天津",""),
new CityEntity(,"重庆",""),
new CityEntity(,"北海",""),
new CityEntity(,"香港","")
};
//投影出 CityEntity 实体类的 ID,Name 字段信息
var v = from lp in cityEntity
select new
{
lp.ID,
lp.Name
};
autoCompleteBox1.DataContext = v.ToList();
//AutoCompleteBox 要显示的字段名
autoCompleteBox1.ValueMemberPath = "Name";
//当输入字符后延迟多少毫秒开始进行匹配,默认0
autoCompleteBox1.MinimumPopulateDelay = ;
//最小输入的字符长度,当输入大于等于此长度时,才进行匹配,默认1
autoCompleteBox1.MinimumPrefixLength = ;
//自定义匹配的模式,如果要实现自已的匹配方法,一定要设置为Custom,已预置了约13种方法
autoCompleteBox1.FilterMode = AutoCompleteFilterMode.Custom;
//填充前事件 动态赋值填充数据源数据 在这里编写
autoCompleteBox1.Populating += new PopulatingEventHandler(autoCompleteBox1_Populating);
//填充匹配操作 比如用汉字首字母匹配汉字 在这里编写代码
autoCompleteBox1.ItemFilter += ItemFilter;
}
void autoCompleteBox1_Populating(object sender, PopulatingEventArgs e)
{
e.Cancel = true;//一定要指定已处理此处理,取消此事件
//根据用户输入的字符串 动态从数据库中 提取相匹配的数据
List<CityEntity> cityEntity = new List<CityEntity>() {
new CityEntity(,"北京1",""),
new CityEntity(,"北京2",""),
new CityEntity(,"北京3",""),
new CityEntity(,"北京4","")
};
var v = from lp in cityEntity
select new { lp.ID, lp.Name };
autoCompleteBox1.DataContext = v.ToList();
autoCompleteBox1.ValueMemberPath = "Name";
autoCompleteBox1.PopulateComplete();//一定要指定填充完成,可以进行匹配操作,从而自动引发ItemFilter 事件
}
public bool ItemFilter(string search, object item)
{
//search 就是用户输入的关键字。
//item是就ItemSource中的项,本例是(object(string)),也可以复杂类型,但要求实现IEnumerable接口
//可以根据相应的逻辑再做进一步处理。为提高性能就在填充前对数据源作处理,此处仅为演示。
//要匹配的文本信息
string tbText = GetPropertyValue(item, "Name").ToString().ToLower();
//原文本再拼接原文本的首字
tbText = tbText + GetFirstLetter(tbText).ToLower();
//搜索匹配关键字
if (tbText.Contains(search.ToLower()))
{
return true;//返回True表示此项匹配,会出现在下拉选框中
}
return false;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
if (autoCompleteBox1.SelectedItem != null)
{
//返回SelectedItem绑定的对象信息
object ci = (object)autoCompleteBox1.SelectedItem;
//输出绑定对象的ID信息
MessageBox.Show("您选中的内容ID是---" + GetPropertyValue(ci, "ID").ToString());
}
}
////微软的转换方法 比较简洁 //工具包下载地址http://www.microsoft.com/zh-cn/download/details.aspx?id=15251
////using Microsoft.International.Converters.PinYinConverter;
////using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
///// <summary>
///// 获取汉字首字母
///// </summary>
///// <param name="str"></param>
///// <returns></returns>
//public static string GetPinYinInitial(string str)
//{
// string r = string.Empty;
// foreach (char obj in str)
// {
// try
// {
// ChineseChar chineseChar = new ChineseChar(obj);
// string t = chineseChar.Pinyins[0].ToString();
// r += t.Substring(0, 1);
// }
// catch
// {
// r += obj.ToString();
// }
// }
// return r;
//}
#region 取中文首字母
public static string GetFirstLetter(string paramChinese)
{
string strTemp = "";
int iLen = paramChinese.Length;
int i = ;
for (i = ; i <= iLen - ; i++)
{
strTemp += GetCharSpellCode(paramChinese.Substring(i, ));
}
return strTemp;
}
/// <summary>
/// 得到一个汉字的拼音第一个字母,如果是一个英文字母则直接返回大写字母
/// </summary>
/// <param name="CnChar">单个汉字</param>
/// <returns>单个大写字母</returns>
private static string GetCharSpellCode(string paramChar)
{
long iCnChar;
byte[] ZW = System.Text.Encoding.Default.GetBytes(paramChar);
//如果是字母,则直接返回
if (ZW.Length == )
{
return paramChar.ToUpper();
}
else
{
// get the array of byte from the single char
int i1 = (short)(ZW[]);
int i2 = (short)(ZW[]);
iCnChar = i1 * + i2;
}
//expresstion
//table of the constant list
// 'A'; //45217..45252
// 'B'; //45253..45760
// 'C'; //45761..46317
// 'D'; //46318..46825
// 'E'; //46826..47009
// 'F'; //47010..47296
// 'G'; //47297..47613
// 'H'; //47614..48118
// 'J'; //48119..49061
// 'K'; //49062..49323
// 'L'; //49324..49895
// 'M'; //49896..50370
// 'N'; //50371..50613
// 'O'; //50614..50621
// 'P'; //50622..50905
// 'Q'; //50906..51386
// 'R'; //51387..51445
// 'S'; //51446..52217
// 'T'; //52218..52697
//没有U,V
// 'W'; //52698..52979
// 'X'; //52980..53640
// 'Y'; //53689..54480
// 'Z'; //54481..55289
// iCnChar match the constant
if ((iCnChar >= ) && (iCnChar <= ))
{
return "A";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "B";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "C";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "D";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "E";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "F";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "G";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "H";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "J";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "K";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "L";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "M";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "N";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "O";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "P";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "Q";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "R";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "S";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "T";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "W";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "X";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "Y";
}
else if ((iCnChar >= ) && (iCnChar <= ))
{
return "Z";
}
else return ("?");
}
#endregion
/// <summary>
/// 获取一个类指定的属性值
/// </summary>
/// <param name="info">object对象</param>
/// <param name="field">属性名称</param>
/// <returns></returns>
public static object GetPropertyValue(object info, string field)
{
if (info == null) return null;
Type t = info.GetType();
IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi;
return property.First().GetValue(info, null);
}
/// <summary>
/// 城市实体类
/// </summary>
public class CityEntity
{
/// <summary>
/// 城市ID
/// </summary>
public int ID { get; set; }
/// <summary>
/// 城市名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 城市编号
/// </summary>
public string Code { get; set; }
/// <summary>
/// 城市实体类构造函数
/// </summary>
/// <param name="id">城市ID</param>
/// <param name="name">城市名称</param>
/// <param name="code">城市编号</param>
public CityEntity(int id, string name, string code)
{
ID = id;
Name = name;
Code = code;
}
}
}
}
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls; namespace JiaXinTech.WPF.HotelTerminal
{
/// <summary>
/// Test3.xaml 的交互逻辑
/// </summary>
public partial class Test3 : Window
{
public Test3()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
List<CityEntity> cityEntity = new List<CityEntity>() {
new CityEntity(,"北京",""),
new CityEntity(,"上海",""),
new CityEntity(,"天津",""),
new CityEntity(,"重庆",""),
new CityEntity(,"北海",""),
new CityEntity(,"香港","")
}; //投影出 CityEntity 实体类的 ID,Name 字段信息
var v = from lp in cityEntity
select new { lp.ID, lp.Name }; autoCompleteBox1.DataContext = v.ToList();
//AutoCompleteBox 要显示的字段名
autoCompleteBox1.ValueMemberPath = "Name"; //当输入字符后延迟多少毫秒开始进行匹配,默认0
autoCompleteBox1.MinimumPopulateDelay = ;
//最小输入的字符长度,当输入大于等于此长度时,才进行匹配,默认1
autoCompleteBox1.MinimumPrefixLength = ;
//自定义匹配的模式,如果要实现自已的匹配方法,一定要设置为Custom,已预置了约13种方法
autoCompleteBox1.FilterMode = AutoCompleteFilterMode.Custom;
//填充前事件 动态赋值填充数据源数据 在这里编写
autoCompleteBox1.Populating += new PopulatingEventHandler(autoCompleteBox1_Populating);
//填充匹配操作 比如用汉字首字母匹配汉字 在这里编写代码
autoCompleteBox1.ItemFilter += ItemFilter; } void autoCompleteBox1_Populating(object sender, PopulatingEventArgs e)
{
e.Cancel = true;//一定要指定已处理此处理,取消此事件 //根据用户输入的字符串 动态从数据库中 提取相匹配的数据
List<CityEntity> cityEntity = new List<CityEntity>() {
new CityEntity(,"北京1",""),
new CityEntity(,"北京2",""),
new CityEntity(,"北京3",""),
new CityEntity(,"北京4","")
}; var v = from lp in cityEntity
select new { lp.ID, lp.Name }; autoCompleteBox1.DataContext = v.ToList();
autoCompleteBox1.ValueMemberPath = "Name"; autoCompleteBox1.PopulateComplete();//一定要指定填充完成,可以进行匹配操作,从而自动引发ItemFilter 事件 } public bool ItemFilter(string search, object item)
{
//search 就是用户输入的关键字。
//item是就ItemSource中的项,本例是(object(string)),也可以复杂类型,但要求实现IEnumerable接口
//可以根据相应的逻辑再做进一步处理。为提高性能就在填充前对数据源作处理,此处仅为演示。 //要匹配的文本信息
string tbText = GetPropertyValue(item, "Name").ToString().ToLower(); //原文本再拼接原文本的首字
tbText = tbText + GetFirstLetter(tbText).ToLower(); //搜索匹配关键字
if (tbText.Contains(search.ToLower()))
{
return true;//返回True表示此项匹配,会出现在下拉选框中
}
return false;
} private void button1_Click(object sender, RoutedEventArgs e)
{
if (autoCompleteBox1.SelectedItem != null)
{
//返回SelectedItem绑定的对象信息
object ci = (object)autoCompleteBox1.SelectedItem; //输出绑定对象的ID信息
MessageBox.Show("您选中的内容ID是---" + GetPropertyValue(ci, "ID").ToString()); }
} ////微软的转换方法 比较简洁 //工具包下载地址http://www.microsoft.com/zh-cn/download/details.aspx?id=15251
////using Microsoft.International.Converters.PinYinConverter;
////using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
///// <summary>
///// 获取汉字首字母
///// </summary>
///// <param name="str"></param>
///// <returns></returns>
//public static string GetPinYinInitial(string str)
//{
// string r = string.Empty;
// foreach (char obj in str)
// {
// try
// {
// ChineseChar chineseChar = new ChineseChar(obj);
// string t = chineseChar.Pinyins[0].ToString();
// r += t.Substring(0, 1);
// }
// catch
// {
// r += obj.ToString();
// }
// }
// return r; //} #region 取中文首字母 public static string GetFirstLetter(string paramChinese)
{ string strTemp = ""; int iLen = paramChinese.Length; int i = ; for (i = ; i <= iLen - ; i++)
{ strTemp += GetCharSpellCode(paramChinese.Substring(i, )); } return strTemp; } /// <summary> /// 得到一个汉字的拼音第一个字母,如果是一个英文字母则直接返回大写字母 /// </summary> /// <param name="CnChar">单个汉字</param> /// <returns>单个大写字母</returns> private static string GetCharSpellCode(string paramChar)
{ long iCnChar; byte[] ZW = System.Text.Encoding.Default.GetBytes(paramChar); //如果是字母,则直接返回 if (ZW.Length == )
{
return paramChar.ToUpper(); } else
{ // get the array of byte from the single char int i1 = (short)(ZW[]); int i2 = (short)(ZW[]); iCnChar = i1 * + i2; } //expresstion //table of the constant list // 'A'; //45217..45252 // 'B'; //45253..45760 // 'C'; //45761..46317 // 'D'; //46318..46825 // 'E'; //46826..47009 // 'F'; //47010..47296 // 'G'; //47297..47613 // 'H'; //47614..48118 // 'J'; //48119..49061 // 'K'; //49062..49323 // 'L'; //49324..49895 // 'M'; //49896..50370 // 'N'; //50371..50613 // 'O'; //50614..50621 // 'P'; //50622..50905 // 'Q'; //50906..51386 // 'R'; //51387..51445 // 'S'; //51446..52217 // 'T'; //52218..52697 //没有U,V // 'W'; //52698..52979 // 'X'; //52980..53640 // 'Y'; //53689..54480 // 'Z'; //54481..55289 // iCnChar match the constant if ((iCnChar >= ) && (iCnChar <= ))
{ return "A"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "B"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "C"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "D"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "E"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "F"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "G"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "H"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "J"; } else if ((iCnChar >= ) && (iCnChar <= ))
{
return "K"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "L"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "M"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "N"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "O"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "P"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "Q"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "R"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "S"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "T"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "W"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "X"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "Y"; } else if ((iCnChar >= ) && (iCnChar <= ))
{ return "Z";
}
else return ("?"); } #endregion /// <summary>
/// 获取一个类指定的属性值
/// </summary>
/// <param name="info">object对象</param>
/// <param name="field">属性名称</param>
/// <returns></returns>
public static object GetPropertyValue(object info, string field)
{
if (info == null) return null;
Type t = info.GetType();
IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi;
return property.First().GetValue(info, null);
} /// <summary>
/// 城市实体类
/// </summary>
public class CityEntity
{
/// <summary>
/// 城市ID
/// </summary>
public int ID { get; set; }
/// <summary>
/// 城市名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 城市编号
/// </summary>
public string Code { get; set; } /// <summary>
/// 城市实体类构造函数
/// </summary>
/// <param name="id">城市ID</param>
/// <param name="name">城市名称</param>
/// <param name="code">城市编号</param>
public CityEntity(int id, string name, string code)
{
ID = id;
Name = name;
Code = code;
}
}
} }

WPF Toolkit AutoCompleteBox 实体类绑定 关键字自定义关联搜索匹配的更多相关文章

  1. WPF中Image控件绑定到自定义类属性

    首先我们定义一个Student类,有ID,Name,Photo(保存图片路径). using System; using System.Collections.Generic; using Syste ...

  2. [转]C#反射,根据反射将数据库查询数据和实体类绑定,并未实体类赋值

    本文来自:http://www.cnblogs.com/mrchenzh/archive/2010/05/31/1747937.html /****************************** ...

  3. com.google.gson的SerializedName解决实体类与关键字的重名

    使用google的gson包,解决实体类中字段与java关键字的重名: // 比如 当实体类中有switch关键字时,解决冲突如下 @SerializedName("switch" ...

  4. WPF toolkit AutoCompleteBox

    checked http://www.broculos.net/2014/04/wpf-autocompletebox-autocomplete-text.html#.WGNnq4N95aQ. 1.S ...

  5. 关于spring MVC 绑定json字符串与实体类绑定

    1 如果前台传json字符串,后台用@RequestBody 接收 前端 "content-Type":"application/json", 2  前台用fo ...

  6. WPF——传实体类及绑定实体类属性

    public class User: private string _User; public string User1 { get { return _User; } set { _User = v ...

  7. [转]掌握 ASP.NET 之路:自定义实体类简介 --自定义实体类和DataSet的比较

    转自: http://www.microsoft.com/china/msdn/library/webservices/asp.net/CustEntCls.mspx?mfr=true 发布日期 : ...

  8. 关于mysql下hibernate实体类字段与数据库关键字冲突的问题

    好久没写了,都忘记博客了,趁着现在还在公司,写的东西是经过验证的,不是在家凭记忆力写的,正确率有保障,就说说最近遇到的一件事情吧. 以前一直用的oracle数据库,这次项目我负责的模块所在的系统是用的 ...

  9. 修改tt模板让ADO.NET C# POCO Entity Generator With WCF Support 生成的实体类继承自定义基类

    折腾几天记载一下,由于项目实际需要,从edmx生成的实体类能自动继承自定义的基类,这个基类不是从edmx文件中添加的Entityobject. 利用ADO.NET C# POCO Entity Gen ...

随机推荐

  1. SQL中Group By的使用(转)

    1.概述 “Group By”从字面意义上理解就是根据“By”指定的规则对数据进行分组,所谓的分组就是将一个“数据集”划分成若干个“小区域”,然后针对若干个“小区域”进行数据处理. 2.原始表 3.简 ...

  2. C# 发布APP修改APP图标以及名称

    很多时候,我们用C#编程后,都要对我们的上位机生成的图标跟名字进行修改,下面我就 VS2015 怎么修改做个说明. 1.打开项目属性 2.打开应用程序的属性界面,对相应的地方进行修改就可以了 3.修改 ...

  3. 异构关系数据库(Sqlserver与Oracle)之间的数据类型转换参考

    一.Oracle到SqlServer的数据类型的转变 编号 Oracle ToSqlServer SqlServer 1 BINARY_DOUBLE VARCHAR(100) real 2 BINAR ...

  4. java中new一个对象的执行过程及类的加载顺序

    1,new一个对象时代码的执行顺序 (1)加载父类(以下序号相同,表明初始化是按代码从上到下的顺序来的) 1.为父类的静态属性分配空间并赋于初值 1.执行父类静态初始化块; (2)加载子类 2.为子类 ...

  5. table的创建

    results为table的行信息 columnNames  是table列名 //创建并初始化table: table =new JTable(results,columNames); //设置ta ...

  6. COGS——T 2342. [SCOI2007]kshort || BZOJ——T 1073

    http://www.cogs.pro/cogs/problem/problem.php?pid=2342 ★★☆   输入文件:bzoj_1073.in   输出文件:bzoj_1073.out   ...

  7. codevs——T1814 最长链

    http://codevs.cn/problem/1814/  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 De ...

  8. [JZOJ 4307] [NOIP2015模拟11.3晚] 喝喝喝 解题报告

    题目链接: http://172.16.0.132/senior/#main/show/4307 题目: 解题报告: 题目询问我们没出现坏对的连续区间个数 我们考虑从左到有枚举右端点$r$,判断$a[ ...

  9. [poj 2185] Milking Grid 解题报告(KMP+最小循环节)

    题目链接:http://poj.org/problem?id=2185 题目: Description Every morning when they are milked, the Farmer J ...

  10. 乔治·霍兹(George Hotz):特斯拉、谷歌最可怕的对手!

    17岁破解iPhone,21岁攻陷索尼PS3:现在,他是埃隆·马斯克最可怕的对手.   黑客往事   许多年后,当乔治·霍兹(George Hotz)回首往事,一定会把2007年作为自己传奇人生的起点 ...