Existe um controle de cronômetro no WPF (. net 4)?
Existe um controle de cronómetro no WPF (. net 4)?
Eu esperava que o Controle do DatePicker tivesse a capacidade de mostrar dados ou uma hora ou ambas, mas não parece. Qualquer uma destas caberia na conta para mim.Wednesday, February 8th, 2012 2:27 pm
- ou:
2:27 pm
(que eu usaria em conjunto com um leitor de dados)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
actualizado (depois de tentar instalar os controlos WPF EXTENDIDOS):
Então ... lá se vai isso / que não é tão fácil como parece/deve ser.quando tentei baixar a caixa de ferramentas extendida do WPF de http://wpftoolkit.codeplex.com/releases/view/71499 entrei na minha janela de download:
Http://download.codeplex.com/site/pagenotfound?ReferenceId=f1704e1d-3152-4ecf-b2bb-ace62735bcbc
(note a parte "page not found" - nada baixado).
... Então eu continuei para o plano B e tentei baixar/instalar Nuget, para que eu pudesse obter a ferramenta extendida WPF dessa forma (via Tools | Extension Manager | Online Gallery | Updates (1) | NeGet Package Manager | Download).
eu primeiro tive que desligar a caixa dizendo "proteger - me de código potencialmente malicioso" (ou algo para esse efeito-eu tinha tentado (duas vezes!) sem desligar essa opção, e esta estoirou ambas as vezes); e depois (depois de desligar a opção) que vi na janela de instalação, "esta extensão contém uma assinatura digital com um certificado inválido."
continuou de qualquer forma, e finalmente conseguiu instalar o Nuget.
Depois de reiniciar o Visual Studio 2010 fui ao Tools | Library Package Manager | Package Manager Console, mas foi recebido com o erro: O Pacote Manager Console requer PowerShell 2.0 runtime, que não é detectado nesta máquina. Instale por favor a PowerShell 2. 0 de http://support.microsoft.com/kb/968929 e reiniciar o Visual Studio.rt Visual Studio."
Então, quando fui instalar a actualização (WindowsXP-KB968930-x86-ENG.exe), i got ," the update / update.a aplicação exe não pode ser executada no modo Win32."e não conseguiu prosseguir. Achhh!!! Parece uma segunda-feira!4 answers
O WPF 4.0 não fornece um leitor de dados da caixa.
Actualizado Eu sou usado o Extended WPF Toolkit http://wpftoolkit.codeplex.com/ num projecto recente, inclui um bom controlo de vectores de Dados - http://wpftoolkit.codeplex.com/wikipage?title=DateTimePicker&referringTitle=Home.
Desculpa por esta imprecisão.Verifique o conjunto de ferramentas extendido do WPF DateTimeUpDown no Codeplex (ou relacionado com o SO post).
Picker Temporal WPF
Ou podes fazer o teu próprio
A minha solução para controlo de tempo simples
Controlo de tempo.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>
Controlo de tempo.xaml.cs (Código atrás)
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 { }
}
}
}
Utilização:
<ctrl:TimeControl Value="{Binding StartTime, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="startTime"/>
Onde 'ctrl' é o espaço de nomes onde o controlo de tempo está localizado, e 'StartTime' é uma propriedade do tipo 'TimeSpan'.
xmlns:ctrl="clr-namespace:Infra.UICommon.Controls;assembly=Infra.UICommon"
Espero que isto ajude.
P. S. A única coisa que não é tratada aqui são as teclas 'backspace' e 'delete'.