2013-07-11 69 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 
     } 
    } 
}