2012-12-05 59 views
1

我想創建一個給定的控件(在這種情況下,它是文本框)的驗證規則。WPF DependencyProperty驗證綁定到對象屬性

儘管採取了適當的步驟,但我無法獲得成功綁定到對象的屬性:ValidationRule和DepedencyProperty被利用。

請在下面找到代碼。值得注意的是,自定義Validation類中的「Is Required」始終爲False,除非我明確地在XAML中設置了值(根據「Is Ranged」參數,沒有綁定)。

任何提示和建議表示讚賞。

預先感謝您:)

XAML代碼:

<TextBox Style="{StaticResource ValidationError}" LostFocus="ForceValidationCheck" 
     Visibility="{Binding Type, Converter={StaticResource Visibility}, ConverterParameter='Number'}" 
     IsEnabled="{Binding RelativeSource={x:Static RelativeSource.Self}, Converter={StaticResource IsEnabled}}"> 
    <TextBox.Text> 
     <Binding Path="Value"> 
      <Binding.ValidationRules> 
       <validation:NumericValidation> 
        <validation:NumericValidation.Dependency> 
         <validation:NumericDependency IsRequired="{Binding Path=IsRequired}" IsRanged="True" Min="5"/> 
        </validation:NumericValidation.Dependency> 
       </validation:NumericValidation> 
      </Binding.ValidationRules> 
     </Binding> 
    </TextBox.Text> 
</TextBox> 

校驗類:

public NumericDependency Dependency { get; set; } 

public override ValidationResult Validate(object value, CultureInfo cultureInfo) 
{ 
    isRequired = Dependency.IsRequired; 
} 

驗證相關性類:

public static readonly DependencyProperty IsRequiredProperty = 
     DependencyProperty.Register("IsRequired", typeof(bool), typeof(NumericDependency), new UIPropertyMetadata(default(bool))); 

public bool IsRequired 
{ 
    get 
    { 
     return (bool) GetValue(IsRequiredProperty); 
    } 
    set 
    { 
     SetValue(IsRequiredProperty, value); 
    } 
} 

回答

3

您可以使用代理。它將允許你將屬性綁定到你的ValidationRule。

Proxy example

下面是一個代碼示例,可以幫助你:在自定義的驗證類

<Utils:Proxy In="{Binding IsRequired, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" Out="{Binding ElementName=numericValidationRule, Path=IsRequired}" /> 
<TextBox> 
    <TextBox.Text> 
     <Binding Path="Value"> 
      <Binding.ValidationRules> 
       <NumericValidation x:Name="numericValidationRule" /> 
      </Binding.ValidationRules> 
     </Binding> 
    </TextBox.Text> 
</TextBox> 
+0

鏈接已死亡。 – Endery

0

還有另一種方式implem確認控制的確認。但是,我仍然想知道如何解決我最初的問題,所以任何幫助表示讚賞。

另一種方式是實現模型的IDataErrorInfo接口。

例子:

public string this[string columnName] 
{ 
    get 
    { 
     if (string.Equals(columnName, "Value", StringComparison.CurrentCultureIgnoreCase)) 
     { 
      string value = Convert.ToString(Value); 

      if (string.IsNullOrEmpty(value) && IsRequired) 
      { 
       return ValidationMessage.RequiredValue; 
      } 
     } 

     return string.Empty; 
    } 
} 
1

IsRequired始終爲false,因爲「Dependency」對象不是邏輯樹的一部分,所以不能使用ElementName或DataContext作爲內部數據綁定的源。

解決這個問題是基於以下 托馬斯·萊維斯克的文章:http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

你必須創建一個繼承「可凍結」,並宣佈一個數據依賴屬性的類。可冷凍類的有趣的特點是可凍結對象甚至可以繼承DataContext的,當他們在視覺或邏輯樹不是:

public class BindingProxy : Freezable 
{ 
    #region Overrides of Freezable 
    protected override Freezable CreateInstanceCore() 
    { 
     return new BindingProxy(); 
    } 
    #endregion 

    public object Data 
    { 
     get { return (object)GetValue(DataProperty); } 
     set { SetValue(DataProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty DataProperty = 
     DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); 
} 

然後你可以在你的文本資源宣佈這個類的一個實例最後

<TextBox.Resources> 
    <local:BindingProxy x:Key="proxy" Data="{Binding}"/> 
<TextBox.Resources/> 

,指定該BindingProxy對象作爲源用於結合:,和數據屬性綁定到當前的DataContext

<validation:NumericDependency IsRequired="{Binding Source={StaticResource proxy} Path=Data.IsRequired}" IsRanged="True" Min="5"/> 

請注意綁定路徑必須以「數據」作爲前綴,因爲路徑現在是相對於BindingProxy對象的。