web-dev-qa-db-fra.com

Quel est actuellement le meilleur sélecteur de temps libre pour WPF?

Je cherche un simple sélecteur de temps control pour WPF.

  • J'ai trouvé trouvé celui-ci:

http://marlongrech.wordpress.com/2007/11/18/time-picker/

mais il a quelques issues par ex. vous ne pouvez pas taper "00" dedans, le deuxième zéro n'apparaîtra pas.

  • Silverlight semble en avoir un:

http://jesseliberty.com/2009/03/28/toolkit-control-%E2%80%93-timepicker/

mais c'est pas pour WPF .

  • Le toolkit WPF a un DatePicker mais pas un TimePicker en lui-même. Ou existe-t-il un moyen d'autoriser l'utilisateur à entrer l'heure et la date dans le WPFToolkit DatePicker? Il retourne un DateTime dans SelectedDate mais je ne vois pas comment permettre à l'utilisateur de choisir également l'heure avec ce contrôle.

Quel est le meilleur contrôle libre WPF permettant aux utilisateurs de saisir l'heure au format HH: MM: SS?

19
Edward Tanguay

Comme vous le voyez ici , vous pouvez vous lancer facilement. Et de cette façon, vous pouvez obtenir exactement ce que vous voulez.

2
Bryan Rowe

J'aime les contrôles de la boîte à outils WPF étendue: Lien vers le code source sur github

Dans le package, le DateTimeUpDown est contenu et peut être utilisé à cette fin. Si vous ne souhaitez pas utiliser la partie Date de celle-ci, vous pouvez définir la Format sur "ShortTime" ou le format de votre choix.

J'espère que cela pourra aider.

23
Sören

Je ne pouvais pas en trouver un sur le Web, alors je l'ai créé à partir de zéro. Je ne comprends pas complètement les propriétés de dépendance, je les ai donc omises pour le moment. Le contrôle est un sélecteur de temps de 12 heures. Je suis nouveau dans WPF, je ne comprends donc pas bien toutes les nouvelles syntaxes de langage, mais ce contrôle me convient parfaitement dans le projet que je crée chez moi.

Il prend en charge la définition de l'heure en tant que DateTime ou TimeSpan.

Ci-dessous, je vais coller le XAML et le code-derrière. Le 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>

Le code-derrière

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
    }
}

C'est le contrôle, n'hésitez pas à faire des modifications si nécessaire. Ce n'est pas parfait mais c'est mieux que les autres contrôles que j'ai trouvés

5
Adam H.

La bibliothèque MahApps possède un contrôle Timepicker depuis la version 1.3.0.

0
xmedeko