C# 限制WPF中的输入

C# 限制WPF中的输入,c#,.net,wpf,xaml,C#,.net,Wpf,Xaml,我正在创建一个自定义控件,当在XAML中调用该控件时,可以将其设置为仅允许某些类型的输入: 其中UnsignedIntegersOnly是包含允许的限制集的枚举的一部分 如果用户输入了不允许的内容,控件将抛出一个验证错误,并且不允许他继续下一个表单/页面/等等 我实现这一点的设想是,在构成此控件的底层文本框中,将其文本字段绑定到验证规则,该规则将作为输入传递CustomControl XAML声明中指定的RestrictTo值。然后在该ValidationRule类中,处理RestrictTo

我正在创建一个自定义控件,当在XAML中调用该控件时,可以将其设置为仅允许某些类型的输入:

其中UnsignedIntegersOnly是包含允许的限制集的枚举的一部分

如果用户输入了不允许的内容,控件将抛出一个验证错误,并且不允许他继续下一个表单/页面/等等

我实现这一点的设想是,在构成此控件的底层文本框中,将其文本字段绑定到验证规则,该规则将作为输入传递CustomControl XAML声明中指定的RestrictTo值。然后在该ValidationRule类中,处理RestrictTo特定验证并返回验证是否成功

这就是我不太确定如何进行的地方。甚至可以以这种看似动态的方式将参数传递给ValidationRule吗?我正在设置控件的属性RestrictTo,然后将其传递给它的验证


如果可能的话,怎么做?我应该使用哪种绑定或资源链接?

您可能对使用MaskedTextBox控件感兴趣,它将限制用户在TextBox中输入的内容

由于微软没有对WPF进行正式控制,我建议Xceed提供以下建议:

(免费使用:-)

这里有掩码的语法:


如果您有Visual Studio 2012,您可以通过NuGet轻松获得此软件包:

(右键单击您的项目)


注意:在回答之前的问题时,我在我发布的链接中广泛使用了验证规则,但我想说,如果有时可以通过精心设计的组件/控件来避免验证,那么这样做是明智的。正如@Barn在您之前的问题中指出的,通用验证规则可能很难做到,而且有些可疑,因为您必须处理其中的所有类型,在我看来,这有点违反直觉,因为验证器和转换器通常针对多面手;你可能会在它上面浪费太多的时间,而且它的可重用性可能比你想象的要低。(来源:我的经验)

您可能对使用MaskedTextBox控件感兴趣,它将限制用户可以在文本框中输入的内容

由于微软没有对WPF进行正式控制,我建议Xceed提供以下建议:

(免费使用:-)

这里有掩码的语法:


如果您有Visual Studio 2012,您可以通过NuGet轻松获得此软件包:

(右键单击您的项目)


注意:在回答之前的问题时,我在我发布的链接中广泛使用了验证规则,但我想说,如果有时可以通过精心设计的组件/控件来避免验证,那么这样做是明智的。正如@Barn在您之前的问题中指出的,通用验证规则可能很难做到,而且有些可疑,因为您必须处理其中的所有类型,在我看来,这有点违反直觉,因为验证器和转换器通常针对多面手;你可能会在它上面浪费太多的时间,而且它的可重用性可能比你想象的要低。(来源:我的经验)

下面的代码应该可以帮助您开始。它是一个用户控件,而不是自定义控件。我建议您首先将代码作为用户控件使用,然后将其转换为自定义控件。将有效属性绑定到viewmodel中控制用户工作流的某些属性

XAML:


下面的代码应该让您开始。它是一个用户控件,而不是自定义控件。我建议您首先将代码作为用户控件使用,然后将其转换为自定义控件。将有效属性绑定到viewmodel中控制用户工作流的某些属性

XAML:


我最大的问题是,我遵循一个非常严格的关注点分离体系结构。我不希望在控件的代码背后有任何验证逻辑。我希望它通过绑定无缝集成。根据我的经验,维护非常高级别的模块化和分离使得维护代码变得非常容易。很多时候,我不得不修改非常非常耦合的代码,并且需要花费很长时间来进行小的更改。我喜欢这个屏蔽文本框,但不幸的是,我不能使用任何第三方软件包(策略)。关于字段,它们要么是字符串,要么是数字,因此每个类型和每个控件都应该有一个验证规则。如果比这更复杂,也许你可以创建多个控件而不是一个。您可以通过使用仅包含有效值的列表框或组合框来限制用户。你试过我在回答时解释的模式了吗?此外,我建议您编辑您的问题,并发布更多细节和代码,例如,一个具体的案例,说明您的困境。我最大的问题是,我遵循一个非常严格的关注点分离体系结构。我不希望在控件的代码背后有任何验证逻辑。我希望它通过绑定无缝集成。根据我的经验,维护非常高级别的模块化和分离使得维护代码变得非常容易。很多时候,我不得不修改非常非常耦合的代码,并且需要花费很长时间来进行小的更改。我喜欢这个屏蔽文本框,但不幸的是,我不能使用任何第三方软件包(策略)。关于字段,它们要么是字符串,要么是数字,因此每个类型和每个控件都应该有一个验证规则。如果比这更复杂,也许你可以创建多个控件而不是一个。您可以通过使用仅包含有效值的列表框或组合框来限制用户。你有没有试过我说的模式
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <xctk:MaskedTextBox Mask="0000"></xctk:MaskedTextBox>
    </Grid>
</Window>
<UserControl x:Class="WpfApplication.ValidatingControl"
             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" 
             mc:Ignorable="d" >
    <StackPanel Orientation="Horizontal">
        <TextBox Name="_textBox" TextChanged="OnTextChanged" Background="LightGray" Width="200"/>
        <TextBlock Name="_messageText" Foreground="Red" />
    </StackPanel>
</UserControl>
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication
{
    public partial class ValidatingControl : UserControl
    {
        public ValidatingControl()
        {
            InitializeComponent();
        }

        public enum Restrictions
        {
            UnsignedIntegersOnly,
            SmallIntegersOnly        
        }

        public static readonly DependencyProperty RestrictToProperty =
            DependencyProperty.Register("RestrictTo", typeof(Restrictions), typeof(ValidatingControl), new PropertyMetadata(Restrictions.UnsignedIntegersOnly));

        public Restrictions RestrictTo
        {
            get { return (Restrictions)GetValue(RestrictToProperty); }
            set { SetValue(RestrictToProperty, value); }
        }

        public bool Valid
        {
            get { return (bool)GetValue(ValidProperty); }
            set { SetValue(ValidProperty, value); }
        }

        public static readonly DependencyProperty ValidProperty =
            DependencyProperty.Register("Valid", typeof(bool), typeof(ValidatingControl), new UIPropertyMetadata(false));

        private void OnTextChanged(object sender, TextChangedEventArgs e)
        {
            ValidateText(RestrictTo, _textBox.Text);
        }

        private void ValidateText(Restrictions restrictTo, string text)
        {
            // validate text, update _messageText, update Valid 
        }
    }
}