Tôi có quan điểm mô hình với 2 thuộc tính: Avà Bvà 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 Agiá 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 Bthự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:
Akhông hợp lệ sau khi nhập 11, mà của sửa từ 11 > 2. Thay đổi Bthành 22khô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 22vào Bviền đỏ (lỗi xác thực) sẽ biến mất và A = 11, B = 22sẽ là các giá trị nguồn trong mô hình xem.
Làm thế nào tôi có thể Bxác nhận bằng cách nào đó buộc Axác thực sau khi Bgiá 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);
}
}
INotifyDataErrorInfotrong 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)?