gpt4 book ai didi

c# - 如何使用 INotifyDataErrorInfo 接口(interface)验证 Observable 集合

转载 作者:行者123 更新时间:2023-11-30 16:50:31 24 4
gpt4 key购买 nike

我正在使用 MVVM 模式并使用 Prism 框架开发 WPF 应用程序。

我有一个基本的数据类如下。

public class ProductDecorator : DecoratorBase<Product>
{
private string _ProductShortName;
private Boolean _IsSelected = false;

// I have omitted some code for clarity here.

[Required]
public int ProductID
{
get { return BusinessEntity.ProductID; }
set
{
SetProperty(() => BusinessEntity.ProductID == value,
() => BusinessEntity.ProductID = value);
}
}

public Boolean IsSelected
{
get { return _IsSelected; }
set
{
SetProperty(ref _IsSelected, value);
}
}
}

我在 ViewModel 中创建了上述数据类的可观察集合。

public class SaleInvoiceViewModel {

private ObservableCollection<ProductDecorator> _productDecorators;
public ObservableCollection<ProductDecorator> ProductDecorators
{
get { return _productDecorators; }
set { SetProperty(ref _productDecorators, value); }
}
}

然后我将这个可观察集合限制在 View 中的列表框中。

<telerik:RadListBox ItemsSource="{Binding ProductDecorators}" HorizontalAlignment="Stretch" Margin="5,10,5,5" Grid.Column="1" VerticalAlignment="Top">
<telerik:RadListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Margin="2" IsChecked="{Binding IsSelected}" />
<TextBlock Text="{Binding ProductShortName}" FontSize="14" />
</StackPanel>
</DataTemplate>
</telerik:RadListBox.ItemTemplate>
</telerik:RadListBox>

从上面的上下文来看,我想验证“用户必须至少选择列表框中的一项”。换句话说,IsSelected 属性在 可观察集合ProductUmDecorator 类之一中必须为 true ProductUmDecorators.

目前我使用 INotifyDataErrorInfo 接口(interface)和 Data Annotations 作为验证规则。我忘记了我应该如何实现我的问题来实现此验证

最佳答案

在 stackoverflow 上有很多与此主题相关的问题,但没有可靠的答案。所以我决定发布我的解决方案作为这个问题的答案。问题的上下文是检查“用户必须在与可观察集合绑定(bind)的列表框中选择一项”。

第一步,ObservableCollection 中的项(实体)需要IsSelected 属性。

public class ProductDecorator : DecoratorBase<Product>
{
private string _ProductShortName;
private Boolean _IsSelected = false;

// I have omitted some code for clarity here.

public Boolean IsSelected
{
get { return _IsSelected; }
set
{
SetProperty(ref _IsSelected, value);
}
}
}

第二步,ObservableCollection中的每一项都必须实现INotifyPropertyChanged接口(interface)。然后您可以访问 PropertyChanged 事件处理程序。

第三步,您需要将以下方法附加到ObservableCollectionCollectionChanged 事件处理程序。

public class SaleInvoiceViewModel {

private ObservableCollection<ProductDecorator> _productDecorators;
public ObservableCollection<ProductDecorator> ProductDecorators
{
get { return _productDecorators; }
set { SetProperty(ref _productDecorators, value); }
}

public SaleInvoiceViewModel() {
_productDecorators= new ObservableCollection<ProductDecorator>();
_productDecorators.CollectionChanged += ContentCollectionChanged;
}

public void ContentCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach(ProductDecorator item in e.OldItems)
{
//Removed items
item.PropertyChanged -= EntityPropertyChanged;
}
}
else if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach(ProductDecorator item in e.NewItems)
{
//Added items
item.PropertyChanged += EntityPropertyChanged;
}
}
}
}

仔细看上面代码中的EntityPropertyChanged方法。只要 ObservableCollection 中任何项目的任何属性发生更改,就会触发此方法。然后,您可以简单地在 EntityPropertyChanged 方法中调用 Validate 方法。

private void EntityPropertyChanged( object sender, PropertyChangedEventArgs e )
{
if (e.PropertyName == "IsSelected")
this.Product.ValidateProperty("ProductUmDecorators");
}

如果更改的属性是 IsSelected,将运行 ValidatedProperty 方法。我将省略 ValidateProperty 方法的详细实现。此方法将尝试使用 DataAnnotations 验证属性,并在出现任何错误时触发 ErrorChanged 事件。可以详细了解here .

最后,您需要在您的 Entity/ViewModel/Decorator 类中实现自定义 DataAnnotation ValidationAttribute,您的 ObservableCollection 属性存在于以下代码中.

public class SaleInvoiceViewModel {

private ObservableCollection<ProductDecorator> _productDecorators;
[AtLeastChooseOneItem(ErrorMessage = "Choose at least one item in the following list.")]
public ObservableCollection<ProductDecorator> ProductDecorators
{
get { return _productDecorators; }
set { SetProperty(ref _productDecorators, value); }
}
}

public class AtLeastChooseOneItem : ValidationAttribute
{
protected override ValidationResult IsValid( object value, ValidationContext validationContext )
{
ProductDecorator tmpEntity = (ProductDecorator) validationContext.ObjectInstance;
var tmpCollection = (ObservableCollection<ProductUmDecorator>) value;

if ( tmpCollection.Count == 0 )
return ValidationResult.Success;

foreach ( var item in tmpCollection )
{
if ( item.IsSelected == true )
return ValidationResult.Success;
}

return new ValidationResult( ErrorMessage );
}
}

这是一个有点复杂的解决方案,但这是迄今为止我找到的最可靠的解决方案。

关于c# - 如何使用 INotifyDataErrorInfo 接口(interface)验证 Observable 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34973407/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com