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 Toolkitをそのまま入手できました(ツール|エクステンションマネージャー|オンラインギャラリー|更新(1)| NeGetパッケージマネージャー|ダウンロード)。
最初に「悪意のある可能性のあるコードから保護してください」というボックスのチェックを外す必要がありました(またはその効果があるため、そのチェックボックスのチェックを外すことなく(2回)試しましたが、両方ともクラッシュしました)。そして(ボックスのチェックを外した後)インストールダイアログで、「この拡張機能には無効な証明書を持つデジタル署名が含まれています」と表示されました。
とにかく続けて、最後にNugetをインストールしました。
Visual Studio 2010を再起動した後、[ツール]に移動しました|ライブラリパッケージマネージャー|パッケージマネージャーコンソールがエラーで迎えられました:パッケージマネージャーコンソールにはPowerShell 2.0ランタイムが必要ですが、このマシンでは検出されません。 http://support.Microsoft.com/kb/968929 からPowerShell 2.0をインストールし、Visual Studio.rt Visual Studioを再起動してください。
次に、その更新プログラム(WindowsXP-KB968930-x86-ENG.exe)をインストールしようとすると、「update/update.exeアプリケーションをWin32モードで実行できません」というメッセージが表示されました。続行できませんでした。
ああ!!!月曜日のように感じます!
WPF 4.0は、そのままではDateTimePickerを提供しません。
Updated私はExtendedWPF Toolkit http ://wpftoolkit.codeplex.com/ 最近のプロジェクトでは、素敵なDateTimePickerコントロールが含まれています- http://wpftoolkit.codeplex.com/wikipage?title=DateTimePicker&referringTitle=Home 。
この不正確さについてすみません。
Extended WPF Toolkitをチェックアウト DateTimeUpDown Codeplexで(または related SO post)。
WPFは正式には作成しませんが、この男が何をしたかを確認できます。
WPFタイムピッカー
または、自分で作ることができます
シンプルな時間制御のための私のソリューション
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"
お役に立てれば)
追伸ここで処理されない唯一のものは、「バックスペース」キーと「削除」キーです。