2013-03-18 42 views
2

我有兩個TextBox控件(如下所示),並希望將第一個TextBox的文本[x:Name="defPointFrom1Txt"]傳遞到第二個TextBox的[ValidationRule [MinIntegerValidationRule]而不是當前值爲1.我可以在代碼中通過命名驗證規則並在第一個TextBox中的值更改時基於事件進行設置。但是,有沒有辦法在XAML中做到這一點,以保持所有的驗證邏輯在一個地方?將文本框中的值傳遞到驗證規則

  <TextBox x:Name="defPointFrom1Txt" Grid.Row="2" Grid.Column="1" Style="{StaticResource lsDefTextBox}" 
        Text="{Binding Path=OffensePointsAllowed[0].From}" IsEnabled="False"/> 
      <TextBox x:Name="defPointTo1Txt" Grid.Row="2" Grid.Column="2" Style="{StaticResource lsDefTextBox}" 
        LostFocus="defPointTo1Txt_LostFocus"> 
       <TextBox.Text> 
        <Binding Path="OffensePointsAllowed[0].To" StringFormat="N1"> 
         <Binding.ValidationRules> 
          <gui:MinIntegerValidationRule Min="1"/> 
         </Binding.ValidationRules> 
        </Binding> 
       </TextBox.Text> 
      </TextBox> 

我的驗證規則代碼如下,以確保完整性。

public class IntegerValidationRule : ValidationRule 
{ 

    public override ValidationResult Validate(object value, CultureInfo cultureInfo) 
    { 
     float controlValue; 
     try 
     { 
      controlValue = int.Parse(value.ToString()); 
     } 
     catch (FormatException) 
     { 
      return new ValidationResult(false, "Value is not a valid integer."); 
     } 
     catch (OverflowException) 
     { 
      return new ValidationResult(false, "Value is too large or small."); 
     } 
     catch (ArgumentNullException) 
     { 
      return new ValidationResult(false, "Must contain a value."); 
     } 
     catch (Exception e) 
     { 
      return new ValidationResult(false, string.Format("{0}", e.Message)); 
     } 
     return ValidationResult.ValidResult; 
    } 

} 

public class MinIntegerValidationRule : IntegerValidationRule 
{ 
    public int Min { get; set; } 

    public override ValidationResult Validate(object value, CultureInfo cultureInfo) 
    { 

     ValidationResult retValue = base.Validate(value, cultureInfo); 
     if (retValue != ValidationResult.ValidResult) 
     { 
      return retValue; 
     } 
     else 
     { 
      float controlValue = int.Parse(value.ToString()); 
      if (controlValue < Min) 
      { 
       return new ValidationResult(false, string.Format("Please enter a number greater than or equal to {0}.",Min)); 
      } 
      else 
      { 
       return ValidationResult.ValidResult; 
      } 
     } 
    } 
} 

UPDATE:

爲響應回答以下問題,我試圖創建一個DependencyObject的。我這樣做,如下所示,但不知道如何在ValidationRule代碼中使用它(或者甚至是我正確創建它)。

public abstract class MinDependencyObject : DependencyObject 
{ 
    public static readonly DependencyProperty MinProperty = 
     DependencyProperty.RegisterAttached(
     "Min", typeof(int), 
     typeof(MinIntegerValidationRule), 
     new PropertyMetadata(), 
     new ValidateValueCallback(ValidateInt) 
    ); 

    public int Min 
    { 
     get { return (int)GetValue(MinProperty); } 
     set { SetValue(MinProperty, value); } 
    } 
    private static bool ValidateInt(object value) 
    { 
     int test; 
     return (int.TryParse(value.ToString(),out test)); 
    } 
} 
+0

你在一個很好的方式。如何實現「ValidateValueCallback」? – DHN 2013-03-19 15:17:57

+1

它通過檢查值來實現.ToString可以被成功解析爲整數。我放棄了在XAML中這樣做。在查看「正確」解決方案後,我決定根據事件設置代碼中的最小和最大範圍。儘管我更喜歡將這個邏輯放在XAML中,但「正確的」解決方案是一種解決方法,因爲「ValidationRule」不會從「DependencyObject」繼承。因此你不能直接設置'DependencyProperty'。即使單獨創建一個「DependencyProperty」並將它放入類中後,仍然無法將其用於綁定。請參閱下面的答案鏈接... – Harrison 2013-03-19 16:23:33

回答

1

您不能在Min屬性上設置綁定,因爲它不是依賴項屬性。我曾經做過的事情是,在viewmodel上創建一個驗證屬性屬性,它給了我類的實例對象,然後我根據它進行驗證。

在你的情況下,我會創建Min作爲依賴對象。

+0

+1嗯,也是一個不錯的主意。 – DHN 2013-03-18 15:17:11

+0

我從來沒有創建一個自定義的DependencyObject。你能解釋一下怎麼做。我已經看過文檔,它很混亂。我將在上面發佈一個編輯,以瞭解到目前爲止所做的工作。 – Harrison 2013-03-18 16:02:59

+0

@哈里森我的意思是DependencyProperty。 – TYY 2013-03-18 16:34:55

0

那麼,如果你認爲在Binding上,你將不得不實施一個相對巨大的開銷來使用它,因爲你的驗證類已經從另一個類繼承。問題在於使用Binding綁定目標必須是DependencyProperty(因爲您可以閱讀here),您無法直接在您的驗證類中實現該目標。

因此,您可以創建例如一個AttachedProperty爲您的驗證類,以便您能夠使用Binding。你可以找到一些信息here