【问题标题】:How do I handle DependencyProperty overflow situations?如何处理 DependencyProperty 溢出情况?
【发布时间】:2017-01-10 00:39:45
【问题描述】:

我有一个 UserControl 和一个名为 Value 的 int DependencyProperty。这绑定到UserControl 上的文本输入。

public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(QuantityUpDown), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged, CoerceValue));

public int Value
{
    get { return (int) GetValue(ValueProperty); }
    set { SetValue(ValueProperty, value); }
}

private static object CoerceValue(DependencyObject d, object basevalue)
{
    //Verifies value is not outside Minimum or Maximum
    QuantityUpDown upDown       = d as QuantityUpDown;
    if (upDown == null)
        return basevalue;

    if ((int)basevalue <= 0 && upDown.Instrument != null)
        return upDown.Minimum;

    //Stocks and ForEx can have values smaller than their lotsize (which is assigned to Minimum)
    if (upDown.Instrument != null && 
        upDown.Instrument.MasterInstrument.InstrumentType != Cbi.InstrumentType.Stock &&
        upDown.Instrument.MasterInstrument.InstrumentType != Cbi.InstrumentType.Forex)
        return Math.Max(Math.Min(upDown.Maximum, (int)basevalue), upDown.Minimum);

    if (upDown.Instrument == null)
        return Math.Max(Math.Min(upDown.Maximum, (int)basevalue), upDown.Minimum);

    if (upDown.Instrument.MasterInstrument.InstrumentType == Cbi.InstrumentType.Stock ||
        upDown.Instrument.MasterInstrument.InstrumentType == Cbi.InstrumentType.Forex)
        return Math.Min(upDown.Maximum, (int)basevalue);

    return basevalue;
}

如果用户在文本框中输入大于int.MaxValue 的值,当该值进入CoerceValue 时,baseValue 参数为1。如果我在@987654329 上提供验证值回调,也会发生同样的情况@。

我想自己处理这种情况,比如将传入的值设置为int.MaxValue。有没有办法做到这一点?

【问题讨论】:

  • 如果您需要在绑定将值传递给源属性之前进行验证(即目标 == TextBox.Text,源 == QuantityUpDown.Value),您可以使用 Binding.ValidationRules 进行验证。
  • 属性类型为int。因此,传递给 Coerce 方法的值不能大于 int.MaxValue
  • @Clemens,很明显。然而,用户可以输入一个大于 int.MaxValue 的值。我该如何处理这种情况?

标签: c# wpf


【解决方案1】:

int 属性永远不能设置为 int 值以外的其他值。但是,TextBox 的 Text 属性的类型是 string,并且当运行时尝试将您的 int 属性设置为不代表有效整数的 string 值时会发生错误。

您的依赖属性对此无能为力,因为它永远不会被设置。正如@@Ed Plunkett 在他的评论中建议的那样,您可以在值转换发生之前使用 ValidationRule 做一些事情,并在转换失败时向用户显示错误消息:

public class StringToIntValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        int i;
        if (int.TryParse(value.ToString(), out i))
            return new ValidationResult(true, null);

        return new ValidationResult(false, "Please enter a valid integer value.");
    }
}

<TextBox>
    <TextBox.Text>
        <Binding Path="Value" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:StringToIntValidationRule ValidationStep="RawProposedValue"/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

有关更多信息,请参阅以下有关 WPF 中数据验证的博客文章:https://blog.magnusmontin.net/2013/08/26/data-validation-in-wpf/

【讨论】:

  • 有没有办法将它与IDataErrorInfo 结合起来?我在我的视图中使用了这个代码。但是,我还需要在 VM 中实现一些东西来处理这个错误。我所做的是,检查 ErrorCollection 是否为空,然后确定 RelayCommand 是否启用/禁用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多