在WPF4.0中,并没有内置的时间选择器控件。虽然市场上有许多第三方的时间选择器控件,但它们的行为和机制可能并不能完全满足需求。因此,本文将介绍如何从设计师的角度出发,使用Expression Blend4和C#编程语言,创建一个自定义的时间选择器控件。
请注意,本文是关于如何为应用程序创建自定义控件的入门文章。文章将提供如何使用现有控件设计自己的自定义控件的见解,并在文章末尾提供创建可重用自定义控件(带有注册属性)的建议。
在Expression Blend4中,按照以下步骤进行:
布局
在LayoutRoot中添加一个Grid(这是父容器)。
将Grid的背景颜色设置为"#000000"。
在刚刚添加的Grid中添加一个StackPanel。
将StackPanel的方向设置为"horizontal"。
将StackPanel的垂直对齐和水平对齐设置为"stretch"。
在StackPanel中添加一个ToggleButton。
布局应该类似于图1。
ToggleButton - 编辑模板
右键点击ToggleButton,然后点击"编辑模板" -> "编辑副本"。
选择ContentPresenter并剪切,选择Chrome并删除。
选择时间轴中的Template,然后从资源库中添加一个Grid。
选择Grid并将ContentPresenter粘贴到里面(对象和时间轴面板应该类似于图2(a))。
确保时间轴中选择了Template节点。
转到触发器标签,添加一个新属性(见图2b)。
将属性更改为IsChecked,并将值设置为"true"(见图2b)。
现在选择Template内的Grid,并将背景颜色更改为"#FF919191"。
返回到Window范围。
布局 - 最后一步
将ToggleButton重命名为"HrBtn"。
选择ToggleButton并添加一个TextBlock。
将TextBlock重命名为"HrTxt",并将前景颜色设置为"#FFFFFFFF"。
选择ToggleButton并复制。
在StackPanel内粘贴三个ToggleButton副本。
将新副本的ToggleButton重命名为"MinBtn"、"SecBtn"和"AmPmBtn"。
将每个ToggleButton内的TextBlock重命名为"MinTxt"、"SecTxt"和"AmPmTxt"。
在StackPanel中添加两个其他TextBlock,并将它们的Text属性设置为":"。
在StackPanel中添加两个Button控件,并将它们重命名为"upBtn"和"downBtn"。
将这些Button控件的Text属性分别设置为"Up"和"Down"。
重新排列时间轴,使其类似于下图所示:
控件应该类似于这样:
在upBtn_Click事件处理程序下,添加以下代码:
if (HrBtn.IsChecked == true) {
int hour = int.Parse(HrTxt.Text);
if (hour == 12) hour = hour - hour;
hour++;
HrTxt.Text = hour.ToString();
} else if (MinBtn.IsChecked == true) {
int min = int.Parse(MinTxt.Text);
if (min == 59) min = -1;
min++;
if (min.ToString().Length == 1) {
MinTxt.Text = "0" + min.ToString();
} else {
MinTxt.Text = min.ToString();
}
} else if (SecBtn.IsChecked == true) {
int sec = int.Parse(SecTxt.Text);
if (sec == 59) sec = -1;
sec++;
if (sec.ToString().Length == 1) {
SecTxt.Text = "0" + sec.ToString();
} else {
SecTxt.Text = sec.ToString();
}
} else if (AmPmBtn.IsChecked == true) {
if (AmPmTxt.Text == "AM") {
AmPmTxt.Text = "PM";
} else {
AmPmTxt.Text = "AM";
}
}
在downBtn_Click事件处理程序下,添加以下代码:
if (HrBtn.IsChecked == true) {
int hour = int.Parse(HrTxt.Text);
if (hour == 1) hour = 13;
hour--;
HrTxt.Text = hour.ToString();
} else if (MinBtn.IsChecked == true) {
int min = int.Parse(MinTxt.Text);
if (min == 0) min = 60;
min--;
if (min.ToString().Length == 1) {
MinTxt.Text = "0" + min.ToString();
} else {
MinTxt.Text = min.ToString();
}
} else if (SecBtn.IsChecked == true) {
int sec = int.Parse(SecTxt.Text);
if (sec == 0) sec = 60;
sec--;
if (sec.ToString().Length == 1) {
SecTxt.Text = "0" + sec.ToString();
} else {
SecTxt.Text = sec.ToString();
}
} else if (AmPmBtn.IsChecked == true) {
if (AmPmTxt.Text == "AM") {
AmPmTxt.Text = "PM";
} else {
AmPmTxt.Text = "AM";
}
}
如果对设计特别擅长,尤其是在Expression Blend中,可以按照自己的喜好来设计控件。最终的Time Watcher 5.0应用程序的控件看起来像这样:
当创建一个可重用的控件时,它必须是"可换肤"的;如果正在创建一个可重用的控件,使用WPF命令模型(参见"命令模型概述")比引发点击事件更好。一个可绑定的DateTime或TimeSpan属性也将使用户能够绑定到它。