【问题标题】:Time Entry/picker control in WPFWPF 中的时间输入/选择器控件
【发布时间】:2010-07-06 12:51:27
【问题描述】:

WPF 中是否有任何时间输入/选择器控件可用,例如日期选择器?

谢谢

【问题讨论】:

    标签: c# wpf controls


    【解决方案1】:

    我在网上找不到,所以我从头开始创建它。我并不完全理解依赖属性,所以我暂时省略了这些。该控件是一个 12 小时时间选择器控件。我是 WPF 的新手,所以我不完全理解所有新的语言语法,但是这个控件可以在我在家创建的项目中为我解决问题。

    支持将时间设置为 DateTime 或 TimeSpan。

    下面我将粘贴 XAML 和代码隐藏。 XAML

    <UserControl x:Class="WorkDayManager3.WPF.UserControls.TimeControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="35" d:DesignWidth="100">
        <Border BorderBrush="LightBlue" BorderThickness="1" Margin="1">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition Width="5" />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <TextBox x:Name="txtHours" BorderThickness="0" MaxLength="2" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Text="1" KeyUp="txt_KeyUp" MouseWheel="txt_MouseWheel" PreviewKeyUp="txt_PreviewKeyUp" />
                <TextBlock Text=":" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
                <TextBox x:Name="txtMinutes" BorderThickness="0" MaxLength="2" TextAlignment="Center" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" Text="00" KeyUp="txt_KeyUp" MouseWheel="txt_MouseWheel" PreviewKeyUp="txt_PreviewKeyUp" />
                <TextBox x:Name="txtAmPm" BorderThickness="0" MaxLength="2" TextAlignment="Center" Grid.Column="3" HorizontalAlignment="Left" VerticalAlignment="Center" PreviewTextInput="txtAmPm_PreviewTextInput" Text="AM" KeyUp="txt_KeyUp" MouseWheel="txt_MouseWheel" Padding="0, 0, 3, 0" />
                <Grid Grid.Column="4">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Button x:Name="btnUp" Focusable="False" Click="btnUp_Click">
                        <TextBlock Text="p" FontFamily="Wingdings 3" HorizontalAlignment="Center" VerticalAlignment="Center" />
                    </Button>
                    <Button x:Name="btnDown" Grid.Row="1" Focusable="False" Click="btnDown_Click">
                        <TextBlock Text="q" FontFamily="Wingdings 3" HorizontalAlignment="Center" VerticalAlignment="Center" />
                    </Button>
                </Grid>
            </Grid>
        </Border>
    </UserControl>
    

    代码隐藏

    using System;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    
    namespace WorkDayManager3.WPF.UserControls
    {
        /// <summary>
        /// Interaction logic for TimeControl.xaml
        /// </summary>
        public partial class TimeControl : UserControl
        {
            public TimeControl()
            {
                InitializeComponent();
            }
    
            #region Properties
    
            /// <summary>
            /// Gets or sets the date time value.
            /// </summary>
            /// <value>The date time value.</value>
            public DateTime? DateTimeValue
            {
                get
                {
                    string hours = this.txtHours.Text;
                    string minutes = this.txtMinutes.Text;
                    string amPm = this.txtAmPm.Text;
                    if (!string.IsNullOrWhiteSpace(hours)
                        && !string.IsNullOrWhiteSpace(minutes)
                        && !string.IsNullOrWhiteSpace(amPm))
                    {
                        string value = string.Format("{0}:{1} {2}", this.txtHours.Text, this.txtMinutes.Text, this.txtAmPm.Text);
                        DateTime time = DateTime.Parse(value);
                        return time;
                    }
                    else
                    {
                        return null;
                    }
                }
                set
                {
                    DateTime? time = value;
                    if (time.HasValue)
                    {
                        string timeString = time.Value.ToShortTimeString();
                        //9:54 AM
                        string[] values = timeString.Split(':', ' ');
                        if (values.Length == 3)
                        {
                            this.txtHours.Text = values[0];
                            this.txtMinutes.Text = values[1];
                            this.txtAmPm.Text = values[2];
                        }
                    }
                }
            }
    
            /// <summary>
            /// Gets or sets the time span value.
            /// </summary>
            /// <value>The time span value.</value>
            public TimeSpan? TimeSpanValue
            {
                get
                {
                    DateTime? time = this.DateTimeValue;
                    if (time.HasValue)
                    {
                        return new TimeSpan(time.Value.Ticks);
                    }
                    else
                    {
                        return null;
                    }
                }
                set
                {
                    TimeSpan? timeSpan = value;
                    if (timeSpan.HasValue)
                    {
                        this.DateTimeValue = new DateTime(timeSpan.Value.Ticks);
                    }
                }
            }
    
            #endregion
    
            #region Event Subscriptions
    
            /// <summary>
            /// Handles the Click event of the btnDown control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
            private void btnDown_Click(object sender, RoutedEventArgs e)
            {
                string controlId = this.GetControlWithFocus().Name;
                if ("txtHours".Equals(controlId))
                {
                    this.ChangeHours(false);
                }
                else if ("txtMinutes".Equals(controlId))
                {
                    this.ChangeMinutes(false);
                }
                else if ("txtAmPm".Equals(controlId))
                {
                    this.ToggleAmPm();
                }
            }
    
            /// <summary>
            /// Handles the Click event of the btnUp control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
            private void btnUp_Click(object sender, RoutedEventArgs e)
            {
                string controlId = this.GetControlWithFocus().Name;
                if ("txtHours".Equals(controlId))
                {
                    this.ChangeHours(true);
                }
                else if ("txtMinutes".Equals(controlId))
                {
                    this.ChangeMinutes(true);
                }
                else if ("txtAmPm".Equals(controlId))
                {
                    this.ToggleAmPm();
                }
            }
    
            /// <summary>
            /// Handles the PreviewTextInput event of the txtAmPm control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.Windows.Input.TextCompositionEventArgs"/> instance containing the event data.</param>
            private void txtAmPm_PreviewTextInput(object sender, TextCompositionEventArgs e)
            {
                // prevent users to type text
                e.Handled = true;
            }
    
            /// <summary>
            /// Handles the KeyUp event of the txt control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.Windows.Input.KeyEventArgs"/> instance containing the event data.</param>
            private void txt_KeyUp(object sender, KeyEventArgs e)
            {
                // check for up and down keyboard presses
                if (Key.Up.Equals(e.Key))
                {
                    btnUp_Click(this, null);
                }
                else if (Key.Down.Equals(e.Key))
                {
                    btnDown_Click(this, null);
                }
            }
    
            /// <summary>
            /// Handles the MouseWheel event of the txt control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.Windows.Input.MouseWheelEventArgs"/> instance containing the event data.</param>
            private void txt_MouseWheel(object sender, MouseWheelEventArgs e)
            {
                if (e.Delta > 0)
                {
                    btnUp_Click(this, null);
                }
                else
                {
                    btnDown_Click(this, null);
                }
            }
    
            /// <summary>
            /// Handles the PreviewKeyUp event of the txt control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.Windows.Input.KeyEventArgs"/> instance containing the event data.</param>
            private void txt_PreviewKeyUp(object sender, KeyEventArgs e)
            {
                TextBox textBox = (TextBox)sender;
                // make sure all characters are number
                bool allNumbers = textBox.Text.All(Char.IsNumber);
                if (!allNumbers)
                {
                    e.Handled = true;
                    return;
                }
    
    
                // make sure user did not enter values out of range
                int value;
                int.TryParse(textBox.Text, out value);
                if ("txtHours".Equals(textBox.Name) && value > 12)
                {
                    EnforceLimits(e, textBox);
                }
                else if ("txtMinutes".Equals(textBox.Name) && value > 59)
                {
                    EnforceLimits(e, textBox);
                }
            }
    
            #endregion
    
            #region Methods
    
            /// <summary>
            /// Changes the hours.
            /// </summary>
            /// <param name="isUp">if set to <c>true</c> [is up].</param>
            private void ChangeHours(bool isUp)
            {
                int value = Convert.ToInt32(this.txtHours.Text);
                if (isUp)
                {
                    value += 1;
                    if (value == 13)
                    {
                        value = 1;
                    }
                }
                else
                {
                    value -= 1;
                    if (value == 0)
                    {
                        value = 12;
                    }
                }
                this.txtHours.Text = Convert.ToString(value);
            }
    
            /// <summary>
            /// Changes the minutes.
            /// </summary>
            /// <param name="isUp">if set to <c>true</c> [is up].</param>
            private void ChangeMinutes(bool isUp)
            {
                int value = Convert.ToInt32(this.txtMinutes.Text);
                if (isUp)
                {
                    value += 1;
                    if (value == 60)
                    {
                        value = 0;
                    }
                }
                else
                {
                    value -= 1;
                    if (value == -1)
                    {
                        value = 59;
                    }
                }
    
                string textValue = Convert.ToString(value);
                if (value < 10)
                {
                    textValue = "0" + Convert.ToString(value);
                }
                this.txtMinutes.Text = textValue;
            }
    
            /// <summary>
            /// Enforces the limits.
            /// </summary>
            /// <param name="e">The <see cref="System.Windows.Input.KeyEventArgs"/> instance containing the event data.</param>
            /// <param name="textBox">The text box.</param>
            /// <param name="enteredValue">The entered value.</param>
            private static void EnforceLimits(KeyEventArgs e, TextBox textBox)
            {
                string enteredValue = GetEnteredValue(e.Key);
                string text = textBox.Text.Replace(enteredValue, "");
                if (string.IsNullOrEmpty(text))
                {
                    text = enteredValue;
                }
                textBox.Text = text;
                e.Handled = true;
            }
    
            /// <summary>
            /// Gets the control with focus.
            /// </summary>
            /// <returns></returns>
            private TextBox GetControlWithFocus()
            {
                TextBox txt = new TextBox();
                if (this.txtHours.IsFocused)
                {
                    txt = this.txtHours;
                }
                else if (this.txtMinutes.IsFocused)
                {
                    txt = this.txtMinutes;
                }
                else if (this.txtAmPm.IsFocused)
                {
                    txt = this.txtAmPm;
                }
                return txt;
            }
    
            /// <summary>
            /// Gets the entered value.
            /// </summary>
            /// <param name="key">The key.</param>
            /// <returns></returns>
            private static string GetEnteredValue(Key key)
            {
                string value = string.Empty;
                switch (key)
                {
                    case Key.D0:
                    case Key.NumPad0:
                        value = "0";
                        break;
                    case Key.D1:
                    case Key.NumPad1:
                        value = "1";
                        break;
                    case Key.D2:
                    case Key.NumPad2:
                        value = "2";
                        break;
                    case Key.D3:
                    case Key.NumPad3:
                        value = "3";
                        break;
                    case Key.D4:
                    case Key.NumPad4:
                        value = "4";
                        break;
                    case Key.D5:
                    case Key.NumPad5:
                        value = "5";
                        break;
                    case Key.D6:
                    case Key.NumPad6:
                        value = "6";
                        break;
                    case Key.D7:
                    case Key.NumPad7:
                        value = "7";
                        break;
                    case Key.D8:
                    case Key.NumPad8:
                        value = "8";
                        break;
                    case Key.D9:
                    case Key.NumPad9:
                        value = "9";
                        break;
                }
                return value;
            }
    
            /// <summary>
            /// Toggles the am pm.
            /// </summary>
            private void ToggleAmPm()
            {
                if ("AM".Equals(this.txtAmPm.Text))
                {
                    this.txtAmPm.Text = "PM";
                }
                else
                {
                    this.txtAmPm.Text = "AM";
                }
            }
    
            #endregion
        }
    }
    

    这就是控件,您可以根据需要随意进行修改。它并不完美,但比我发现的其他控件要好

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 2016-09-18
      • 1970-01-01
      相关资源
      最近更新 更多