programing

WPF(.NET 4)에 TimePicker 컨트롤이 있습니까?

magicmemo 2023. 4. 16. 14:51
반응형

WPF(.NET 4)에 TimePicker 컨트롤이 있습니까?

WPF(.NET 4)에 TimePicker 컨트롤이 있습니까?

DatePicker 컨트롤에 데이터나 시간, 또는 둘 다 표시할 수 있는 기능이 있으면 좋겠다고 생각했습니다만, 그렇지 않은 것 같습니다.다음 중 어느 것이든 제 요구에 맞는 것 같습니다.

Wednesday, February 8th, 2012 2:27 pm

- 또는:

2:27 pm

(DatePicker와 함께 사용합니다)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

갱신(확장 WPF 컨트롤 설치 시도 후):

그것에 대해서는 너무 많다/그것은 말처럼/그만큼 쉽지는 않다.

http://wpftoolkit.codeplex.com/releases/view/71499에서 확장 WPF Toolkit을 다운로드하려고 하면 다운로드 대화상자가 나타납니다.

http://download.codeplex.com/site/pagenotfound?ReferenceId=f1704e1d-3152-4ecf-b2bb-ace62735bcbc

("페이지를 찾을 수 없음" 부분을 참조하십시오. 다운로드된 내용은 없습니다.)

...그래서 B를 계획하여 Nuget을 다운로드/설치하려고 했습니다.이렇게 하면 확장 WPF 툴킷을 입수할 수 있습니다([툴] | [익스텐션 매니저] | [온라인 갤러리] | [업데이트 (1)] | [NeGet 패키지 매니저] | [다운로드] ) 。

처음에 "악성코드로부터 보호해주세요"라는 체크박스를 꺼야 했습니다.(혹은 그 체크박스를 끄지 않고 두 번 시도했는데 두 번 모두 크래쉬가 발생했습니다.)그리고 (박스를 끄면) 설치 대화 상자에 "이 확장자에는 유효하지 않은 증명서를 가진 디지털 서명이 포함되어 있습니다."라고 표시되어 있습니다.

어쨌든 나는 계속했고, 마침내 Nuget을 설치했다.

Visual Studio 2010 재부팅 후 Tools | Library Package Manager | Package Manager Console로 이동했는데 다음 오류가 나타납니다.Package Manager Console에는 PowerShell 2.0 런타임이 필요한데 이 시스템에서 검색되지 않습니다.http://support.microsoft.com/kb/968929에서 PowerShell 2.0을 설치하고 Visual Studio.rt Visual Studio를 재시작하십시오."

그 후, 그 업데이트(WindowsXP-KB968930-x86-ENG.exe)를 인스톨 했을 때에, 「업데이트/업데이트.exe 어플리케이션은 Win32 모드로 실행할 수 없습니다."라는 메시지가 표시되며 계속 진행되지 않았습니다.

아아아아아악!!!월요일 같아!

WPF 4.0 에서는, Date Time Picker 는 곧바로 사용할 수 없습니다.

갱신: 최근 프로젝트에서 Extended WPF Toolkit http://wpftoolkit.codeplex.com/ 를 사용하고 있습니다. 툴킷에는 훌륭한 Date Time Picker Control - http://wpftoolkit.codeplex.com/wikipage?title=DateTimePicker&referringTitle=Home 가 포함되어 있습니다.http://wpftoolkit.codeplex.com/wikipage?title=DateTimePicker&referringTitle=Home

부정확해서 죄송합니다.

Codeplex(또는 관련 SO 포스트)에서 Extended WPF Toolkit Date Time Up Down을 확인합니다.

외부 컨트롤이 없는 Date Time Picker(Extended Toolkit 및 추가 라이선스 없음) 및 상업용도 원하는 경우 기존 Date Time Picker를 개선하여 https://gist.github.com/Apflkuacha/406e755c8b42a70b7ab138e6b985bcdf에서 공유합니다.

선택한 날짜와 시간을 표시하는 필드 및 날짜와 시간을 선택하는 팝업창이 나타납니다.

Date Time Picker(날짜 시간 선택기)

심플한 시간 관리를 위한 솔루션

TimeControl.xaml

<UserControl x:Class="Infra.UICommon.Controls.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" 
             xmlns:local="clr-namespace:Infra.UICommon.Controls"
             mc:Ignorable="d" 
             Height="Auto" Width="Auto" x:Name="UserControl" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid x:Name="LayoutRoot" Width="Auto" Height="Auto" Background="White">
        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="0.2*"/>

            <ColumnDefinition Width="0.05*"/>

            <ColumnDefinition Width="0.2*"/>

            <ColumnDefinition Width="0.05*"/>

            <ColumnDefinition Width="0.2*"/>

            <ColumnDefinition Width="0.05*"/>

            <ColumnDefinition Width="0.2*"/>

        </Grid.ColumnDefinitions>

        <!-- Hours -->
        <Grid x:Name="hours" Focusable="True" MouseWheel="OnMouseWheel" >
            <TextBox x:Name="hh" TextWrapping="Wrap" Text="{Binding Path=Hours, ElementName=UserControl, Mode=Default}" 
                     PreviewKeyDown="OnKeyDown" PreviewTextInput="OnPreviewTextInput"  DataObject.Pasting="OnTextPasting" 
                     TextAlignment="Center" VerticalAlignment="Center"  BorderThickness="0"/>
        </Grid>

        <!-- Separator ':' -->
        <Grid  Grid.Column="1">
            <TextBox IsReadOnly="True" x:Name="sep1" TextWrapping="Wrap" VerticalAlignment="Center" Text=":" TextAlignment="Center"  BorderThickness="0"/>
        </Grid>

        <!-- Minutes -->
        <Grid  Grid.Column="2" x:Name="minutes" Focusable="True" MouseWheel="OnMouseWheel">
            <TextBox  x:Name="mm"  TextWrapping="Wrap" Text="{Binding Path=Minutes, ElementName=UserControl, Mode=Default}" 
                      PreviewKeyDown="OnKeyDown" PreviewTextInput="OnPreviewTextInput"  DataObject.Pasting="OnTextPasting" 
                      TextAlignment="Center" VerticalAlignment="Center" BorderThickness="0" />
        </Grid>

        <!-- Separator ':' -->
        <Grid  Grid.Column="3">
            <TextBox IsReadOnly="True" x:Name="sep2"  TextWrapping="Wrap" VerticalAlignment="Center" Text=":" TextAlignment="Center"  BorderThickness="0"/>
        </Grid>

        <!-- Seconds -->
        <Grid  Grid.Column="4" Name="seconds" Focusable="True" MouseWheel="OnMouseWheel">
            <TextBox x:Name="ss"  TextWrapping="Wrap" Text="{Binding Path=Seconds, ElementName=UserControl, Mode=Default}" 
                     PreviewKeyDown="OnKeyDown" PreviewTextInput="OnPreviewTextInput"  DataObject.Pasting="OnTextPasting" 
                     TextAlignment="Center" VerticalAlignment="Center" BorderThickness="0" />
        </Grid>

        <!-- Separator ':' -->
        <Grid  Grid.Column="5">
            <TextBox IsReadOnly="True" x:Name="sep3"  TextWrapping="Wrap" VerticalAlignment="Center"  Text=":" TextAlignment="Center"  BorderThickness="0"/>
        </Grid>

        <!-- Milliseconds -->
        <Grid  Grid.Column="6" Name="miliseconds" Focusable="True" MouseWheel="OnMouseWheel">
            <TextBox x:Name="ff"  TextWrapping="Wrap" Text="{Binding Path=Milliseconds, ElementName=UserControl, Mode=Default}"
                     PreviewKeyDown="OnKeyDown" PreviewTextInput="OnPreviewTextInput"  DataObject.Pasting="OnTextPasting" 
                     TextAlignment="Center" VerticalAlignment="Center" BorderThickness="0" />
        </Grid>

    </Grid>

</UserControl>

TimeControl.xaml.cs (코드 배면)

namespace Infra.UICommon.Controls
{
    /// <summary>
    /// Interaction logic for TimeControl.xaml
    /// </summary>
    public partial class TimeControl : UserControl
    {
        public TimeControl()
        {
            InitializeComponent();
        }

        private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            TimeControl control = obj as TimeControl;
            var newTime = (TimeSpan)e.NewValue;

            control.Hours        = newTime.Hours;
            control.Minutes      = newTime.Minutes;
            control.Seconds      = newTime.Seconds;
            control.Milliseconds = newTime.Milliseconds;
        }


        private static void OnTimeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            TimeControl control = obj as TimeControl;
            control.Value = new TimeSpan(0, control.Hours, control.Minutes, control.Seconds, control.Milliseconds);
        }

        public TimeSpan Value
        {
            get { return (TimeSpan)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }
        public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(TimeSpan), typeof(TimeControl),
        new FrameworkPropertyMetadata(DateTime.Now.TimeOfDay, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnValueChanged)));



        public int Hours
        {
            get { return (int)GetValue(HoursProperty); }
            set { SetValue(HoursProperty, value); }
        }
        public static readonly DependencyProperty HoursProperty =
        DependencyProperty.Register("Hours", typeof(int), typeof(TimeControl),
        new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnTimeChanged)));

        public int Minutes
        {
            get { return (int)GetValue(MinutesProperty); }
            set { SetValue(MinutesProperty, value); }
        }
        public static readonly DependencyProperty MinutesProperty =
        DependencyProperty.Register("Minutes", typeof(int), typeof(TimeControl),
        new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnTimeChanged)));

        public int Seconds
        {
            get { return (int)GetValue(SecondsProperty); }
            set { SetValue(SecondsProperty, value); }
        }

        public static readonly DependencyProperty SecondsProperty =
        DependencyProperty.Register("Seconds", typeof(int), typeof(TimeControl),
        new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnTimeChanged)));


        public int Milliseconds
        {
            get { return (int)GetValue(MillisecondsProperty); }
            set { SetValue(MillisecondsProperty, value); }
        }

        public static readonly DependencyProperty MillisecondsProperty =
        DependencyProperty.Register("Milliseconds", typeof(int), typeof(TimeControl),
        new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnTimeChanged)));


        private Tuple<int, int> GetMaxAndCurentValues(String name)
        {
            int maxValue = 0;
            int currValue = 0;

            switch (name)
            {
                case "ff":
                    maxValue = 1000;
                    currValue = Milliseconds; 
                    break;

                case "ss":
                    maxValue = 60;
                    currValue = Seconds;
                    break;

                case "mm":
                    maxValue = 60;
                    currValue = Minutes;
                    break;

                case "hh":
                    maxValue = 24;
                    currValue = Hours;
                    break;
            }

            return new Tuple<int, int>(maxValue, currValue);
        }

        private void UpdateTimeValue(String name, int delta)
        {
            var values = GetMaxAndCurentValues(name);
            int maxValue = values.Item1;
            int currValue = values.Item2;

            // Set new value
            int newValue = currValue + delta;

            if (newValue == maxValue)
            {
                newValue = 0;
            }
            else if (newValue < 0)
            {
                newValue += maxValue;
            }


            switch (name)
            {
                case "ff":
                    Milliseconds = newValue;

                    break;

                case "ss":
                    Seconds = newValue;
                    break;

                case "mm":
                    Minutes = newValue;
                    break;

                case "hh":
                    Hours = newValue;
                    break;
            }
        }

        private void OnKeyDown(object sender, KeyEventArgs args)
        {
            try
            {
                int delta = 0;
                String name = ((TextBox)sender).Name;

                if (args.Key == Key.Up) { delta = 1; }
                else if (args.Key == Key.Down) { delta = -1; }

                UpdateTimeValue(name, delta);
            }
            catch { }
        }

        private void OnMouseWheel(object sender, MouseWheelEventArgs e)
        {
            try
            {
                var g = (Grid)(sender);
                var value = g.Children.OfType<TextBox>().FirstOrDefault();

                UpdateTimeValue(value.Name, e.Delta / Math.Abs(e.Delta));
            }
            catch { }

        }

        private Boolean IsTextAllowed(String name, String text)
        {
            try
            {
                foreach (Char c in text.ToCharArray())
                {
                    if (Char.IsDigit(c) || Char.IsControl(c)) continue;
                    else return false;
                }

                var values = GetMaxAndCurentValues(name);
                int maxValue = values.Item1;

                int newValue = Convert.ToInt32(text);

                if (newValue < 0 || newValue >= (Int32)maxValue)
                {
                    return false;
                }

            } catch
            {
                return false;
            }


            return true;
        }

        // Use the OnPreviewTextInput to respond to key presses 
        private void OnPreviewTextInput(Object sender, TextCompositionEventArgs e)
        {
            try
            {
                var tb = (TextBox)sender;


                e.Handled = !IsTextAllowed(tb.Name, tb.Text + e.Text);
            }
            catch { }
        }

        // Use the DataObject.Pasting Handler  
        private void OnTextPasting(object sender, DataObjectPastingEventArgs e)
        {
            try
            {
                String name = ((TextBox)sender).Name;

                if (e.DataObject.GetDataPresent(typeof(String)))
                {
                    String text = (String)e.DataObject.GetData(typeof(String));
                    if (!IsTextAllowed(name, text)) e.CancelCommand();
                }
                else e.CancelCommand();
            }
            catch { }
        }

    }
}

사용방법:

<ctrl:TimeControl Value="{Binding StartTime, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="startTime"/>

여기서 'ctrl'은 TimeControl이 위치한 네임스페이스이고 'StartTime'은 'TimeSpan' 유형의 속성입니다.

xmlns:ctrl="clr-namespace:Infra.UICommon.Controls;assembly=Infra.UICommon"

도움이 되길 바랍니다)

p.s. 여기서 다루지 않는 유일한 것은 '백스페이스'와 '삭제' 키입니다.

WPF는 공식적으로 만들지는 않지만 이 남자가 무엇을 했는지 확인할 수 있습니다.
WPF 임 w w

아니면 당신만의 것을 만들 수도 있다.

언급URL : https://stackoverflow.com/questions/9218258/is-there-a-timepicker-control-in-wpf-net-4

반응형