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에서 공유합니다.
선택한 날짜와 시간을 표시하는 필드 및 날짜와 시간을 선택하는 팝업창이 나타납니다.
심플한 시간 관리를 위한 솔루션
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
'programing' 카테고리의 다른 글
github에서 모든 커밋 이력을 삭제하는 방법 (0) | 2023.04.16 |
---|---|
문자열 길이를 기준으로 Python 목록 정렬 (0) | 2023.04.16 |
인수를 기반으로 WPF를 시작하는 방법 (0) | 2023.04.16 |
WPF DataGrid에서 원클릭 편집 (0) | 2023.04.16 |
wpf 형식의 텍스트로 위첨자 및 아래첨자 설정 (0) | 2023.04.16 |