Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF:将文本框输入格式化为用户类型_C#_Wpf_Xaml_Mvvm - Fatal编程技术网

C# WPF:将文本框输入格式化为用户类型

C# WPF:将文本框输入格式化为用户类型,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,在我们的WPF应用程序中,有几个文本框,用户应该只在其中输入货币。很容易强制文本框在输入时格式化输入: <TextBox Text="{Binding CostOut, StringFormat='{}{0:C}' /> 因为大多数人在数字格式化之前就已经完成了打字,所以这种方法效果更好。然而,这个应用程序很复杂,需要处理重要的财务数据,一些用户在键入数字时会仔细考虑。对于这些速度较慢的打字机,这种延迟仍然会导致它们的输入被重新格式化 我不愿意在“延迟”的路线上走得更远,因为我

在我们的WPF应用程序中,有几个文本框,用户应该只在其中输入货币。很容易强制文本框在输入时格式化输入:

<TextBox Text="{Binding CostOut, StringFormat='{}{0:C}' />

因为大多数人在数字格式化之前就已经完成了打字,所以这种方法效果更好。然而,这个应用程序很复杂,需要处理重要的财务数据,一些用户在键入数字时会仔细考虑。对于这些速度较慢的打字机,这种延迟仍然会导致它们的输入被重新格式化

我不愿意在“延迟”的路线上走得更远,因为我们最终会到达一个点,在有人保存之前,它不会被格式化。我找到并尝试了一个WPF CurrencyTextBox,但由于“收银机”样式的键入太不熟悉而被拒绝作为解决方案


目前建议的解决方案是从应用程序中删除所有格式,并仅在保存时格式化。这让我感觉很激烈,我不禁想知道是否有更好的解决方案?

当文本框在文本框的
LostFocus
事件上失去焦点时,您可以尝试设置所需的格式。它将允许用户键入他/她必须键入的内容,并且不会像在“保存”按钮上设置格式那样激烈。

当文本框在文本框的
LostFocus
事件上失去焦点时,您可以尝试设置所需的格式。这将允许用户键入他/她必须键入的内容,并且不会像在“保存”按钮上设置格式那样激烈

目前建议的解决方案是从应用程序中删除所有格式,并仅在保存时格式化。这让我感觉很激烈,我不禁想知道是否有更好的解决方案

当用户跳出文本框时,只需将绑定的UpdateSourceTrigger属性设置为XAML标记中的默认值LostFocus,即可更新源属性并应用格式:

<TextBox Text="{Binding CostOut, StringFormat={}{0:C}, UpdateSourceTrigger=LostFocus}" />

这至少比保存时应用格式要好一点

另一种选择是使用某种蒙面文本框。没有内置的工具,但您可以尝试开源扩展WPF工具包中提供的工具:

也有商业选择:

目前建议的解决方案是从应用程序中删除所有格式,并仅在保存时格式化。这让我感觉很激烈,我不禁想知道是否有更好的解决方案

当用户跳出文本框时,只需将绑定的UpdateSourceTrigger属性设置为XAML标记中的默认值LostFocus,即可更新源属性并应用格式:

<TextBox Text="{Binding CostOut, StringFormat={}{0:C}, UpdateSourceTrigger=LostFocus}" />

这至少比保存时应用格式要好一点

另一种选择是使用某种蒙面文本框。没有内置的工具,但您可以尝试开源扩展WPF工具包中提供的工具:


还有一些商业选项可用:

如一条评论中所述,我创建了一个小示例,介绍如何将LostFocus事件绑定到ViewModel中的
ICommand
-属性

附加的属性看起来像:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace TextBoxLostFocusBehaviorExample
{
    internal static class TextBoxExtensions
    {
        public static readonly DependencyProperty LostFocusCommandProperty = DependencyProperty.RegisterAttached(
            "LostFocusCommand",
            typeof(ICommand),
            typeof(TextBoxExtensions),
            new PropertyMetadata(default(ICommand), OnLostFocusCommandChanged));

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

            if (e.NewValue != null)
            {
                textBox.LostFocus += TextBoxOnLostFocus;
            }
        }

        private static void TextBoxOnLostFocus(object sender, RoutedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox == null)
            {
                return;
            }

            ICommand command = GetLostFocusCommand(textBox);
            command.Execute(null);
        }

        public static void SetLostFocusCommand(DependencyObject element, ICommand value)
        {
            element.SetValue(LostFocusCommandProperty, value);
        }

        public static ICommand GetLostFocusCommand(DependencyObject element)
        {
            return (ICommand)element.GetValue(LostFocusCommandProperty);
        }
    }
}
<TextBox Text="{Binding CostOut, Mode=TwoWay}" TextBoxLostFocusBehaviorExample:TextBoxExtensions.LostFocusCommand="{Binding LostFocusCommand}"/>
然后,在ViewModel中有一个类型为
ICommand
的属性,该属性可以如下所示:

private ICommand lostFocusCommand;
public ICommand LostFocusCommand
{
    get { return lostFocusCommand ?? (lostFocusCommand = new RelayCommand(p => CostOutLostFocus())); }
}
当触发
LostFocus
-事件时,将调用
CostOutLostFocus
-方法

视图中附加属性的用法如下所示:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace TextBoxLostFocusBehaviorExample
{
    internal static class TextBoxExtensions
    {
        public static readonly DependencyProperty LostFocusCommandProperty = DependencyProperty.RegisterAttached(
            "LostFocusCommand",
            typeof(ICommand),
            typeof(TextBoxExtensions),
            new PropertyMetadata(default(ICommand), OnLostFocusCommandChanged));

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

            if (e.NewValue != null)
            {
                textBox.LostFocus += TextBoxOnLostFocus;
            }
        }

        private static void TextBoxOnLostFocus(object sender, RoutedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox == null)
            {
                return;
            }

            ICommand command = GetLostFocusCommand(textBox);
            command.Execute(null);
        }

        public static void SetLostFocusCommand(DependencyObject element, ICommand value)
        {
            element.SetValue(LostFocusCommandProperty, value);
        }

        public static ICommand GetLostFocusCommand(DependencyObject element)
        {
            return (ICommand)element.GetValue(LostFocusCommandProperty);
        }
    }
}
<TextBox Text="{Binding CostOut, Mode=TwoWay}" TextBoxLostFocusBehaviorExample:TextBoxExtensions.LostFocusCommand="{Binding LostFocusCommand}"/>


TextBoxLostFocusBehaviorExample是定义附加属性的
类的名称空间。

如注释中所述,我创建了一个小示例,介绍如何将LostFocus事件绑定到ViewModel中的
ICommand
-属性

附加的属性看起来像:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace TextBoxLostFocusBehaviorExample
{
    internal static class TextBoxExtensions
    {
        public static readonly DependencyProperty LostFocusCommandProperty = DependencyProperty.RegisterAttached(
            "LostFocusCommand",
            typeof(ICommand),
            typeof(TextBoxExtensions),
            new PropertyMetadata(default(ICommand), OnLostFocusCommandChanged));

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

            if (e.NewValue != null)
            {
                textBox.LostFocus += TextBoxOnLostFocus;
            }
        }

        private static void TextBoxOnLostFocus(object sender, RoutedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox == null)
            {
                return;
            }

            ICommand command = GetLostFocusCommand(textBox);
            command.Execute(null);
        }

        public static void SetLostFocusCommand(DependencyObject element, ICommand value)
        {
            element.SetValue(LostFocusCommandProperty, value);
        }

        public static ICommand GetLostFocusCommand(DependencyObject element)
        {
            return (ICommand)element.GetValue(LostFocusCommandProperty);
        }
    }
}
<TextBox Text="{Binding CostOut, Mode=TwoWay}" TextBoxLostFocusBehaviorExample:TextBoxExtensions.LostFocusCommand="{Binding LostFocusCommand}"/>
然后,在ViewModel中有一个类型为
ICommand
的属性,该属性可以如下所示:

private ICommand lostFocusCommand;
public ICommand LostFocusCommand
{
    get { return lostFocusCommand ?? (lostFocusCommand = new RelayCommand(p => CostOutLostFocus())); }
}
当触发
LostFocus
-事件时,将调用
CostOutLostFocus
-方法

视图中附加属性的用法如下所示:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace TextBoxLostFocusBehaviorExample
{
    internal static class TextBoxExtensions
    {
        public static readonly DependencyProperty LostFocusCommandProperty = DependencyProperty.RegisterAttached(
            "LostFocusCommand",
            typeof(ICommand),
            typeof(TextBoxExtensions),
            new PropertyMetadata(default(ICommand), OnLostFocusCommandChanged));

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

            if (e.NewValue != null)
            {
                textBox.LostFocus += TextBoxOnLostFocus;
            }
        }

        private static void TextBoxOnLostFocus(object sender, RoutedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox == null)
            {
                return;
            }

            ICommand command = GetLostFocusCommand(textBox);
            command.Execute(null);
        }

        public static void SetLostFocusCommand(DependencyObject element, ICommand value)
        {
            element.SetValue(LostFocusCommandProperty, value);
        }

        public static ICommand GetLostFocusCommand(DependencyObject element)
        {
            return (ICommand)element.GetValue(LostFocusCommandProperty);
        }
    }
}
<TextBox Text="{Binding CostOut, Mode=TwoWay}" TextBoxLostFocusBehaviorExample:TextBoxExtensions.LostFocusCommand="{Binding LostFocusCommand}"/>


TextBoxLostFocusBehaviorExample是用于定义附加属性的
类的命名空间。

您使用的.net framework版本是什么?我认为在第四节中有一些问题。0@Pikoh这是4.5我想行为会做得更好。尝试从@WillP answer使用您正在使用的.net framework版本?我认为在第四节中有一些问题。0@Pikoh这是4.5我想行为会做得更好。尝试使用@WillP answer,如果您想知道如何在不破坏MVVM模式的情况下获得该事件,请告诉我。然后我为您写一个小的附加属性。@Tomtom这会很有帮助,谢谢-这就是我最初没有走这条路线的原因。如果您想知道如何在不破坏MVVM模式的情况下获得该事件,请告诉我。然后我给你写一个小的附加属性。@Tomtom那会很有帮助的,谢谢-这就是我当初没有走这条路的原因