如何通过Dependency Property绑定用户控件的ValueRange最大最小值至DataGrid?
问题解决:用户控件自定义范围值绑定到DataGrid验证规则失效的修复
问题根源分析
你的代码存在三个核心错误,导致始终获取Int32RangeChecker的默认值:
- MyUserControl属性逻辑错误:MinRange的getter返回的是maxRange,构造函数赋值顺序完全颠倒
- XAML绑定目标类型错误:RelativeSource指定的
MyForm并非你的用户控件类型,应该是MyUserControl - 嵌套DependencyObject绑定限制:ValidationRule不是DependencyObject,嵌套绑定
Int32RangeChecker的属性无法正确传递值
修正后的完整代码
1. 修复MyUserControl的属性与构造函数
public partial class MyUserControl : UserControl, INotifyPropertyChanged { private int minRange; private int maxRange; public int MaxRange { get => maxRange; set { maxRange = value; OnPropertyChanged(); } } public int MinRange { get => minRange; // 修正:返回正确的私有字段 set { minRange = value; // 修正:赋值给正确的私有字段 OnPropertyChanged(); } } public MyUserControl(int minRange = 0, int maxRange = 500) { InitializeComponent(); // 修正赋值顺序 MinRange = minRange; MaxRange = maxRange; } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 简化验证规则,避免嵌套绑定问题
直接在ValueRangeRule中暴露Min/Max属性,跳过Int32RangeChecker的嵌套绑定:
public class ValueRangeRule : ValidationRule { public int Minimum { get; set; } public int Maximum { get; set; } public override ValidationResult Validate(object value, CultureInfo cultureInfo) { double myValue = 0; try { if (!string.IsNullOrEmpty(value?.ToString())) myValue = double.Parse(value.ToString()); } catch (Exception e) { return new ValidationResult(false, $"非法字符或 {e.Message}"); } if (myValue <= Minimum || myValue >= Maximum) { return new ValidationResult(false, $"请输入 {Minimum}-{Maximum} 范围内的值。"); } return ValidationResult.ValidResult; } }
3. 修正XAML绑定目标
<TextBox.Text> <Binding Path="MyValue" Converter="{StaticResource ConvertString}" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:ValueRangeRule Minimum="{Binding MinRange, RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}}" Maximum="{Binding MaxRange, RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}}" /> </Binding.ValidationRules> </Binding> </TextBox.Text>
额外注意事项
- 确保用户控件的
DataContext未被意外覆盖,否则RelativeSource绑定会失效 - 如果需要动态更新Min/Max值,
MyUserControl的属性已正确触发PropertyChanged事件,验证规则会在绑定源更新时自动重新验证 - 若需实时响应范围值变化并重新验证,可手动调用
TextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource()
内容的提问来源于stack exchange,提问作者abdou_dev
相关产品推荐
相关产品推荐

