TextBox for Time

时间:2015-12-03 11:40:05

标签: c# wpf

在我的应用程序中,我有一个TextBox,用户可以在其中输入HH:mm:ss格式的时间值。

TextBox的xaml看起来像:

<TextBox xMinWidth="60" HorizontalAlignment="Left" Background="Transparent">
    <TextBox.Text>
        <Binding Path="FileTime" UpdateSourceTrigger="PropertyChanged" StringFormat="T" ConverterCulture="de-DE" />         
    </TextBox.Text>
</TextBox>

ViewModel中的属性FileTime的类型为DateTime

如果我尝试输入值13:15:45,TextBox显示我13:15:04,此时我输入4.如果我输入最后5个结果{{1这是13:15:045,这不是一个有效的时间。

如何让TextBox接受单个号码作为秒,并且不会追加前导零?

1 个答案:

答案 0 :(得分:1)

我找到了一个适合我的解决方案,并且每个TextBox都可以轻松重复使用。

我写了AttachedProperty,看起来像是:

public class TextBoxExtensions
{
    public static readonly DependencyProperty EditStringFormatProperty = DependencyProperty.RegisterAttached(
        "EditStringFormat", typeof (string), typeof (TextBoxExtensions),
        new PropertyMetadata(default(string), OnEditStringFormatChanged));

    private static readonly DependencyProperty OriginalBindingExpressionProperty = DependencyProperty
        .RegisterAttached(
            "OriginalBindingExpression", typeof (BindingExpression), typeof (TextBoxExtensions),
            new PropertyMetadata(default(BindingExpression)));

    private static void OnEditStringFormatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBox textBox = d as TextBox;
        if (textBox == null)
            return;

        if (e.NewValue != null && e.OldValue == null)
        {
            textBox.IsKeyboardFocusedChanged += TextBoxOnIsKeyboardFocusedChanged;
        }
        else if (e.OldValue != null && e.NewValue == null)
        {
            textBox.IsKeyboardFocusedChanged -= TextBoxOnIsKeyboardFocusedChanged;
        }
    }

    private static void TextBoxOnIsKeyboardFocusedChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        TextBox textBox = sender as TextBox;

        if (textBox == null)
            return;

        if (GetOriginalBindingExpression(textBox) == null)
        {
            SetOriginalBindingExpression(textBox, textBox.GetBindingExpression(TextBox.TextProperty));
        }

        BindingExpression bindingExpression = GetOriginalBindingExpression(textBox);

        if (textBox.IsKeyboardFocused)
        {
            Binding parentBinding = bindingExpression.ParentBinding;
            Binding newBinding = new Binding(parentBinding.Path.Path)
            {
                ElementName = parentBinding.ElementName,
                Path = parentBinding.Path,
                Mode = parentBinding.Mode,
                UpdateSourceTrigger = parentBinding.UpdateSourceTrigger,
                StringFormat = "H:m:s"
            };
            foreach (ValidationRule validationRule in parentBinding.ValidationRules)
            {
                newBinding.ValidationRules.Add(validationRule);
            }
            textBox.SetBinding(TextBox.TextProperty, newBinding);
        }
        else
        {
            textBox.SetBinding(TextBox.TextProperty, bindingExpression.ParentBinding);
        }
    }

    public static void SetEditStringFormat(DependencyObject element, string value)
    {
        element.SetValue(EditStringFormatProperty, value);
    }

    public static string GetEditStringFormat(DependencyObject element)
    {
        return (string) element.GetValue(EditStringFormatProperty);
    }

    private static void SetOriginalBindingExpression(DependencyObject element, BindingExpression value)
    {
        element.SetValue(OriginalBindingExpressionProperty, value);
    }

    private static BindingExpression GetOriginalBindingExpression(DependencyObject element)
    {
        return (BindingExpression) element.GetValue(OriginalBindingExpressionProperty);
    }
}

用法只是:

<TextBox x:Name="TxtHour" MinWidth="60" HorizontalAlignment="Left" MaxLength="8" Background="Transparent"
         Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}"
         attachedProperties:TextBoxExtensions.EditStringFormat="H:m:s">
    <TextBox.Text>
        <Binding Path="FileTime" UpdateSourceTrigger="PropertyChanged" StringFormat="HH:mm:ss">
            <Binding.ValidationRules>
                <validationRules:StringIsTimeValidationRule />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>