如何处理DependencyProperty溢出情况?

时间:2017-01-09 14:13:59

标签: c# wpf

我有一个名为Value的UserControl和一个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.如果我提供验证,则会出现同样的情况DependencyProperty上的值回调。

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

1 个答案:

答案 0 :(得分:3)

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/