将验证规则应用于ListView的ItemsSource属性

时间:2011-01-18 19:55:14

标签: c# .net wpf validation data-binding

我想通过检查ItemsSource是否包含空集合来验证ListView。这是XAML。

<ListView x:Name="lstvItemsInGroup" 
            <ListView.ItemsSource>
                <Binding Path="ItemsInGroup" Mode="OneWay" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <local:CollectionNotEmptyValidationRule ErrorMessage="You must select at least one item" />
                    </Binding.ValidationRules>
                </Binding> 
            </ListView.ItemsSource>

        </ListView>

这是ValidationRule。

public class CollectionNotEmptyValidationRule : ValidationRule
    {
        public string ErrorMessage
        { get; set; }



    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        ValidationResult lResult = null;

        IEnumerable<object> lCollection = (IEnumerable<object>)value;
        if (lCollection == null || lCollection.Count() == 0)
        {
            lResult = new ValidationResult(false, ErrorMessage);
        }
        else
        {
            lResult = new ValidationResult(true, null);
        }

        return lResult;
    }

我在使用

加载usercontrol时强制进行验证
lstvItemsInGroup.GetBindingExpression(ListView.ItemsSourceProperty).UpdateSource();

但是ValidationRule甚至没有被调用,我在第一行有一个断点而没有。

任何线索?

谢谢。

3 个答案:

答案 0 :(得分:4)

此处http://msdn.microsoft.com/en-us/library/system.windows.data.bindingexpression.updatesource.aspx据说UpdateSource方法仅在绑定处于TwoWayOneWayToSource模式时才更新源。因此,请尝试在绑定上设置Mode=TwoWay

答案 1 :(得分:2)

这有效:

public class CollectionNotEmptyValidationRule : ValidationRule
{
    public CollectionNotEmptyValidationRule()
        : base(ValidationStep.RawProposedValue, true)
    {
    }

    public string ErrorMessage { get; set; }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        return (value as IEnumerable<object>)?.Any() == true
            ? ValidationResult.ValidResult
            : new ValidationResult(false, ErrorMessage);
    }
}
<ListView>
    <ListView.ItemsSource>
        <Binding Mode="OneWay"
                    Path="Empty"
                    UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:CollectionNotEmptyValidationRule ErrorMessage="Collection cannot be empty" />
            </Binding.ValidationRules>
        </Binding>
    </ListView.ItemsSource>
</ListView>

这样做不会跟踪收藏更改。

如果您愿意,可以使用:

public class MinValidationRule : ValidationRule
{
    public static readonly DependencyProperty AssertMinProperty = DependencyProperty.RegisterAttached(
        "AssertMin",
        typeof(int),
        typeof(MinValidationRule),
        new PropertyMetadata(default(int)));

    public MinValidationRule()
        : base(ValidationStep.ConvertedProposedValue, true)
    {
    }

    public string ErrorMessage { get; set; }

    public int Min { get; set; }

    public static void SetAssertMin(DependencyObject element, int value)
    {
        element.SetValue(AssertMinProperty, value);
    }

    public static int GetAssertMin(DependencyObject element)
    {
        return (int)element.GetValue(AssertMinProperty);
    }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        return ((int)value) >= Min
            ? ValidationResult.ValidResult
            : new ValidationResult(false, ErrorMessage);
    }
}
<ListView MinHeight="20" ItemsSource="{Binding VmItems}">
    <local:MinValidationRule.AssertMin>
        <Binding Path="Items.Count" RelativeSource="{RelativeSource Self}">
            <Binding.ValidationRules>
                <local:MinValidationRule ErrorMessage="Collection must have at least one item" Min="1" />
            </Binding.ValidationRules>
        </Binding>
    </local:MinValidationRule.AssertMin>
</ListView>

答案 2 :(得分:0)

如果要验证,则应使用相应的方法,而不是尝试更新源:

BindingExpression.ValidateWithoutUpdate();