2013-07-11 70 views
1

我创建一个定制控制,在XAML调用时可设定为仅允许特定类型的输入:在WPF限制输入

<lib:CustomControl RestrictTo="UnsignedIntegersOnly" ... ></CustomControl>

凡UnsignedIntegersOnly是包含组枚举的一部分允许的限制。

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

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

这是我不太确定如何继续。是否有可能以这种看似动态的方式将参数传递给ValidationRule?我正在设置一个属性RestrictTo,并将其传递给它的验证。

如果可能,它将如何完成?我应该使用什么样的绑定或资源链接?

回答

1

您可能有兴趣使用MaskedTextBox控件,它会限制用户可以在TextBox中输入的内容。

由于有来自微软的官方控制WPF我建议从Xceed如下:

MaskedTextBox(它是免费的:-)

这里有面具的语法使用:

http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask.aspx

<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> 

如果你有Visua升工作室2012,你可以很容易地通过的NuGet得到这个包:

(您的项目右击)

enter image description here

注:在我回答你刚才的问题,我广泛使用的验证规则我发布的链接,但我会说,如果有些时候你可以通过精心设计的组件/控件来避免它,那么明智的做法是。正如@Barn在你之前的问题中指出的那样,一个通用的验证规则可能是一件很难做的事情,有些问题,因为你必须处理所有类型,IMO有点违反直觉,因为验证器和转换器通常具体反对通才;你可能会浪费更多时间,而不是它的价值,它可能会比你想象的更少重复使用。 (来源:我的经验)

+0

我最大的问题是,我下面关注结构非常严格分离。我不想在控件的代码隐藏中有任何验证逻辑。我希望它通过绑定进行无缝集成。根据我的经验,保持非常高的模块性和分离性使维护代码非常容易。很多时候我必须修改代码,这些代码非常非常耦合,并且需要一直进行小的修改。 我喜欢这个Masked TextBox,但不幸的是我不能使用像这样的任何第三方软件包(策略)。 –

+0

关于字段,它们是一个字符串或一个数字,因此每个类型和每个控件应该有一个验证规则。如果它比这更复杂,也许你可以创建多个控件而不是一个。您可以通过仅使用有效值的ListBox或ComboBox来限制用户。您是否尝试了我在http://programmers.stackexchange.com/questions/203590/is-there-an-effective-way-for-creating-complex-forms?答案中解释的模式?另外,我建议你编辑你的问题,并发布更多的细节和更多的代码,一个具体的案例,例如你卡住的地方。 – Aybe

0

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

XAML:

<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 
     } 
    } 
}