65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.36/5 (9投票s)

2011 年 8 月 9 日

CPOL

3分钟阅读

viewsIcon

65990

downloadIcon

4330

在 WPF 4 中创建自定义 TimePicker 控件的步骤。

引言

我正在开发一个应用程序,Time Watcher 5.0,我需要使用 TimePicker 控件,而 WPF 4.0 的控件中没有提供该控件。有几个第三方 TimePicker 控件,但我不满意它们的“操作机制和行为”。以下是我创建自己的自定义 TimePicker 控件的步骤,我知道通过分享这个过程,它将使很多人受益。

请注意这一点!

请注意,这是一篇关于如何从设计师的角度创建应用程序自定义控件的介绍性文章。本文将让您了解如何使用现有控件来设计您自己的自定义控件,并在本文末尾提供关于如何创建可重用自定义控件(具有注册属性)的建议。

在本演示中,我将使用 Expression Blend 4。现在让我们开始吧!

步骤 1 - 设计控件

在 Expression Blend 4 中,执行以下操作

布局

  1. Grid 添加到 LayoutRoot (这是父容器)
  2. Grid 的背景颜色设置为“#000000”
  3. StackPanel 添加到您刚刚添加的 Grid
  4. 将方向设置为“水平”
  5. 将垂直对齐和水平对齐设置为“拉伸”
  6. ToggleButton 添加到 StackPanel

您的布局应与此类似

Layout.jpg

图 1

ToggleButton - 编辑模板

  1. 右键单击 ToggleButton 并单击“编辑模板” ->“编辑副本”。
  2. 选择 ContentPresenter 并剪切,选择 Chrome,然后删除。
  3. 在时间轴中选择 Template,并从资产中添加一个 Grid 到其中。
  4. 选择 Grid 并将 ContentPresenter 粘贴到其中 (您的“对象”和“时间轴”面板应如下图 2(a) 所示)。
  5. 确保在时间轴中选中了 Template 节点。
  6. 转到“触发器”选项卡,添加一个新属性 (请参见图 2b)。
  7. 将属性更改为 IsChecked 并将值设置为“true” (请参见图 2b)。
  8. 现在选择 Template 中的 Grid,并将背景颜色更改为“#FF919191”。
  9. 将范围返回到 Window。

Figure_2a.jpgFigure_2b.png

图 2

布局 - 润色

  1. ToggleButton 重命名为 'HrBtn'。
  2. 选择 ToggleButton,并向其添加一个 TextBlock
  3. TextBlock 重命名为 HrTxt,并将前景色设置为“#FFFFFFFF”。
  4. 选择 ToggleButton 并复制。
  5. ToggleButton 的三个副本粘贴到 StackPanel 中。
  6. ToggleButton 的新副本重命名为 MinBtnSecBtnAmPmBtn
  7. 将每个 ToggleButton 中的 TextBlock 重命名为 MinTxtSecTxtAmPmTxt
  8. 将另外两个 TextBlock 添加到 StackPanel,并将其 Text 属性设置为“:”。
  9. 将两个 Button 控件添加到 StackPanel,并将它们重命名为 upBtndownBtn
  10. 分别将这些 Button 控件的 Text 属性设置为“Up”和“Down”。
  11. 重新排列您的时间轴,使其类似于下面显示的时间轴

Timeline.jpg

您的控件应与此类似

Control.jpg

步骤 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 应用程序的最终控件如下所示

Final.jpg

最后说明

创建可重用控件时,它必须是“可换肤的”;如果您要创建用于重用的控件,使用 WPF 命令模型(请参阅 命令概述)也比引发点击事件更好。一个可绑定的 DateTimeTimeSpan 属性也将使用户能够绑定到此控件。感谢 Keith Barrow 的贡献。

建议

有关如何创建自定义控件和添加依赖属性的更多阅读资料,我推荐 创建 WPF 自定义控件,第 1 部分创建 WPF 自定义控件,第 2 部分,作者:David Veeneman

© . All rights reserved.