Das ist eine Möglichkeit. Es ist schön und einfach, aber ein bisschen chaotisch. Sie können das Storyboard loswerden und bei jedem Tick einen lokalen Wert um das Tick-Intervall erhöhen und damit Ihre Zeit bestimmen. Du hättest dann nur eine Zeiteinheit.
Oder ... Ein eleganter und wiederverwendbarer Weg wäre, eine Hilfsklasse zu erstellen, die ein DependencyObject ist. Ich würde auch ein StoryBoard mit einer DoubleAnimation verwenden und das Storyboard.Target an eine Instanz des DoubleTextblockSetters binden. Setzen Sie das Storyboard Duration auf Ihre Zeit und stellen Sie den Wert auf Ihre Zeit in Sekunden ein. Hier ist der DoublerBlockSetterCode.
public class DoubleTextBlockSetter : DependencyObject
{
private TextBlock textBlock { get; private set; }
private IValueConverter converter { get; private set; }
private object converterParameter { get; private set; }
public DoubleTextBlockSetter(
TextBlock textBlock,
IValueConverter converter,
object converterParameter)
{
this.textBlock = textBlock;
this.converter = converter;
this.converterParameter = converterParameter;
}
#region Value
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
"Value",
typeof(double),
typeof(DoubleTextBlockSetter),
new PropertyMetadata(
new PropertyChangedCallback(
DoubleTextBlockSetter.ValuePropertyChanged
)
)
);
private static void ValuePropertyChanged(
DependencyObject obj,
DependencyPropertyChangedEventArgs args)
{
DoubleTextBlockSetter control = obj as DoubleTextBlockSetter;
if (control != null)
{
control.OnValuePropertyChanged();
}
}
public double Value
{
get { return (double)this.GetValue(DoubleTextBlockSetter.ValueProperty); }
set { base.SetValue(DoubleTextBlockSetter.ValueProperty, value); }
}
protected virtual void OnValuePropertyChanged()
{
this.textBlock.Text = this.converter.Convert(
this.Value,
typeof(string),
this.converterParameter,
CultureInfo.CurrentCulture) as string;
}
#endregion
}
Dann könnten Sie ein Format-Konverter haben:
public class TicksFormatConverter : IValueConverter
{
TimeSpanFormatProvider formatProvider = new TimeSpanFormatProvider();
public object Convert(object value,
Type targetType,
object parameter,
CultureInfo culture)
{
long numericValue = 0;
if (value is int)
{
numericValue = (long)(int)value;
}
else if (value is long)
{
numericValue = (long)value;
}
else if (value is double)
{
numericValue = (long)(double)value;
}
else
throw new ArgumentException("Expecting type of int, long, or double.");
string formatterString = null;
if (parameter != null)
{
formatterString = parameter.ToString();
}
else
{
formatterString = "{0:H:m:ss}";
}
TimeSpan timespan = new TimeSpan(numericValue);
return string.Format(this.formatProvider, formatterString, timespan);
}
public object ConvertBack(
object value,
Type targetType,
object parameter,
CultureInfo culture)
{
throw new NotImplementedException();
}
}
Fast hätte ich vergessen die TimespanFormatProvider. In Silverlight gibt es keinen Formatanbieter für die Zeitspanne, so scheint es.
public class TimeSpanFormatProvider : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType != typeof(ICustomFormatter))
return null;
return this;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
string formattedString;
if (arg is TimeSpan)
{
TimeSpan ts = (TimeSpan)arg;
DateTime dt = DateTime.MinValue.Add(ts);
if (ts < TimeSpan.FromDays(1))
{
format = format.Replace("d.", "");
format = format.Replace("d", "");
}
if (ts < TimeSpan.FromHours(1))
{
format = format.Replace("H:", "");
format = format.Replace("H", "");
format = format.Replace("h:", "");
format = format.Replace("h", "");
}
// Uncomment of you want to minutes to disappear below 60 seconds.
//if (ts < TimeSpan.FromMinutes(1))
//{
// format = format.Replace("m:", "");
// format = format.Replace("m", "");
//}
if (string.IsNullOrEmpty(format))
{
formattedString = string.Empty;
}
else
{
formattedString = dt.ToString(format, formatProvider);
}
}
else
throw new ArgumentNullException();
return formattedString;
}
}
All das Zeug ist wiederverwendbar und sollte in Ihrem Werkzeugkasten leben. Ich habe es von meinem genommen. Dann verkabeln Sie natürlich alles zusammen:
Storyboard sb = new Storyboard();
DoubleAnimation da = new DoubleAnimation();
sb.Children.Add(da);
DoubleTextBlockSetter textBlockSetter = new DoubleTextBlockSetter(
Your_TextBlock,
new TicksFormatConverter(),
"{0:m:ss}"); // DateTime format
Storyboard.SetTarget(da, textBlockSetter);
da.From = Your_RefreshInterval_Secs * TimeSpan.TicksPerSecond;
da.Duration = new Duration(
new TimeSpan(
Your_RefreshInterval_Secs * TimeSpan.TicksPerSecond));
sb.begin();
Und das sollte den Trick tun. Und es ist nur wie eine Million Zeilen Code. Und wir haben noch nicht einmal Hello World geschrieben ...;) Ich habe das nicht kompiliert, aber ich habe die 3 Klassen direkt aus meiner Bibliothek kopieren und einfügen können. Ich habe sie ziemlich oft benutzt. Es funktioniert großartig. Ich benutze diese Klassen auch für andere Dinge. Der TickFormatConverter ist praktisch, wenn Daten gebunden werden. Ich habe auch einen, der Sekunden macht. Sehr hilfreich. Mit dem DoubleTextblockSetter kann ich Zahlen animieren, was wirklich Spaß macht. Vor allem, wenn Sie verschiedene Arten der Interpolation anwenden.
Genießen.
Ich liebte die Visualisierung des Rennens. Gut gemacht. – caryden