I'd like to validate a ListView by checking if the ItemsSource contains an empty collection. Here's the 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>
Here's the 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;
}
I am forcing the validation upon loading the usercontrol with
lstvItemsInGroup.GetBindingExpression(ListView.ItemsSourceProperty).UpdateSource();
But the ValidationRule isn't even called, I have a breakpoint in the first line and nothing.
Any clues?
Thank you.
Here http://msdn.microsoft.com/en-us/library/system.windows.data.bindingexpression.updatesource.aspx it is said that the UpdateSource
method only updates the source if the binding is in TwoWay
or OneWayToSource
modes. So, try setting Mode=TwoWay
on your binding.
This works:
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>
Doing it like this does not track collection changes.
If you want that you can use:
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With