Tôi có quan điểm mô hình với 2 thuộc tính: A
và B
và tôi muốn xác nhận rằng A < B
.
Dưới đây là triển khai đơn giản hóa của tôi, nơi tôi sử dụng quy tắc xác thực tùy chỉnh. Vì mỗi thuộc tính được xác nhận độc lập, dẫn đến một vấn đề gây khó chịu: nếu A
giá trị được nhập không hợp lệ, thì nó vẫn tồn tại ngay cả sau khi thay đổi B
, vì xác B
thực không biết gì về nó A
.
Điều này có thể được nhìn thấy trên bản demo này:
A
không hợp lệ sau khi nhập 11
, mà của sửa từ 11 > 2
. Thay đổi B
thành 22
không đánh giá lại A
, tôi phải chỉnh sửa A
để thông qua xác nhận.
Những gì tôi muốn? Tôi muốn rằng sau khi tham gia 22
vào B
viền đỏ (lỗi xác thực) sẽ biến mất và A = 11, B = 22
sẽ là các giá trị nguồn trong mô hình xem.
Làm thế nào tôi có thể B
xác nhận bằng cách nào đó buộc A
xác thực sau khi B
giá trị mới được đồng bộ hóa với nguồn?
Xem mô hình:
public class ViewModel : INotifyPropertyChanged
{
int _a;
public int A
{
get => _a;
set
{
_a = value;
OnPropertyChanged();
}
}
int _b;
public int B
{
get => _b;
set
{
_b = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertyChanged([CallerMemberName] string property = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
Lượt xem:
<StackPanel>
<TextBox Margin="10" Text="{local:MyBinding A}" />
<TextBox Margin="10" Text="{local:MyBinding B}" />
</StackPanel>
Xem mã:
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel { A = 1, B = 2 };
}
Ràng buộc:
public class MyBinding : Binding
{
public MyBinding(string path) : base(path)
{
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
ValidationRules.Add(new MyValidationRule());
}
}
Quy tắc xác nhận:
public class MyValidationRule : ValidationRule
{
public MyValidationRule() : base(ValidationStep.ConvertedProposedValue, false) { }
public override ValidationResult Validate(object value, CultureInfo cultureInfo) => ValidationResult.ValidResult; // not used
public override ValidationResult Validate(object value, CultureInfo cultureInfo, BindingExpressionBase owner)
{
var binding = owner as BindingExpression;
var vm = binding?.DataItem as ViewModel;
switch (binding.ResolvedSourcePropertyName)
{
case nameof(vm.A):
if ((int)value >= vm.B)
return new ValidationResult(false, "A should be smaller than B");
break;
case nameof(vm.B):
if ((int)value <= vm.A)
return new ValidationResult(false, "B should be bigger than A");
break;
}
return base.Validate(value, cultureInfo, owner);
}
}
INotifyDataErrorInfo
trong mô hình xem của mình nếu bạn muốn thực hiện loại xác nhận này. Nó không được hỗ trợ bởi các quy tắc xác nhận.
A
: trước hoặc sau khi xác thực B
(nói cách khác trước khi giá trị của B được chấp nhận và đồng bộ hóa với nguồn hoặc sau). Vấn đề đặt hàng. Và thực sự trước tiên tôi phải có tất cả các giá trị được sửa đổi và chỉ sau đó thực hiện xác nhận theo thứ tự bình thường.
OnPropertyChanged(nameof(B))
trong setter của mộtA
(và tương đương với setter củaB
)?