在 WPF 4.0 中创建自定义 TimePicker 控件






4.36/5 (9投票s)
在 WPF 4 中创建自定义 TimePicker 控件的步骤。
引言
我正在开发一个应用程序,Time Watcher 5.0,我需要使用 TimePicker 控件,而 WPF 4.0 的控件中没有提供该控件。有几个第三方 TimePicker 控件,但我不满意它们的“操作机制和行为”。以下是我创建自己的自定义 TimePicker 控件的步骤,我知道通过分享这个过程,它将使很多人受益。
请注意这一点!
请注意,这是一篇关于如何从设计师的角度创建应用程序自定义控件的介绍性文章。本文将让您了解如何使用现有控件来设计您自己的自定义控件,并在本文末尾提供关于如何创建可重用自定义控件(具有注册属性)的建议。
在本演示中,我将使用 Expression Blend 4。现在让我们开始吧!
步骤 1 - 设计控件
在 Expression Blend 4 中,执行以下操作
布局
- 将
Grid
添加到 LayoutRoot (这是父容器) - 将
Grid
的背景颜色设置为“#000000” - 将
StackPanel
添加到您刚刚添加的Grid
- 将方向设置为“水平”
- 将垂直对齐和水平对齐设置为“拉伸”
- 将
ToggleButton
添加到StackPanel
您的布局应与此类似
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
并复制。 - 将
ToggleButton
的三个副本粘贴到StackPanel
中。 - 将
ToggleButton
的新副本重命名为MinBtn
、SecBtn
和AmPmBtn
。 - 将每个
ToggleButton
中的TextBlock
重命名为MinTxt
、SecTxt
和AmPmTxt
。 - 将另外两个
TextBlock
添加到StackPanel
,并将其Text
属性设置为“:”。 - 将两个
Button
控件添加到StackPanel
,并将它们重命名为upBtn
和downBtn
。 - 分别将这些
Button
控件的Text
属性设置为“Up”和“Down”。 - 重新排列您的时间轴,使其类似于下面显示的时间轴
您的控件应与此类似
步骤 2 - 编写控件代码
在 upBtn_Click
事件处理程序下,添加以下代码
/*The code below check to see which node is selected in the control,
get the current value of the node, increase the value by one
and display back to the user. This get fired every time the user clicks the 'Up' Button*/
if (HrBtn.IsChecked == true) //If the hour node is selected in the control
{
int hour = int.Parse(HrTxt.Text); //Converts the Text to an Integer
if (hour == 12)
hour = hour - hour;
// This ensures that hour does not exceed
// 12 since hour ranges from 1 to 12
hour++; //Increase the hour by 1
HrTxt.Text = hour.ToString();
//Convert the resulting hour back to string format.
}
else if (MinBtn.IsChecked == true)
{
int min = int.Parse(MinTxt.Text); //Converts the Text to an Integer
if (min == 59)
min = -1; //This ensures that minute does not exceed
//60 since minute ranges from 0 to 59
min++;
if (min.ToString().Length == 1)
// This ensures that the minute text maintain a standard length of 2
{
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 the Am/Pm node is selected,
//the code below alternates between Am and Pm.
if(AmPmTxt.Text == "AM")
{
AmPmTxt.Text = "PM";
}
else
{
AmPmTxt.Text = "AM";
}
}
在 downBtn_Click
事件处理程序下,添加以下代码
/*The code below check to see which node is selected in the control,
get the current value of the node, decrease the value by one
and display back to the user. This get fired every time
the user clicks the 'Down' Button*/
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
属性也将使用户能够绑定到此控件。感谢 Keith Barrow 的贡献。
建议
有关如何创建自定义控件和添加依赖属性的更多阅读资料,我推荐 创建 WPF 自定义控件,第 1 部分 和 创建 WPF 自定义控件,第 2 部分,作者:David Veeneman。