在Silverlight中没有DependencyObject.CoerceValue。我正在寻找一个替代方案,以做以下WPF-代码也在Silverlight。
情况:有一个类范围,它有几个DependencyProperties: MinimumProperty,MaximumProperty,LowerValueProperty和UpperValueProperty。
最小值永远不会大于最大值,最大值永远不会小于最小值。此外,LowerValue和UpperValue必须介于最小值和最大值之间,而LowerValue始终小于UpperValue。
所有的DependencyProperties都是这样实现的(在WPF中):
public static new readonly DependencyProperty MinimumProperty =
DependencyProperty.Register("Minimum",
typeof(double),
typeof(Range),
new FrameworkPropertyMetadata(0d,
new PropertyChangedCallback(Range.OnMinimumChanged),
new CoerceValueCallback(Range.CoerceMinimum)),
new ValidateValueCallback(Range.ValidateMinimum));
public new double Minimum
{
get { return (double)base.GetValue(MinimumProperty); }
set { base.SetValue(MinimumProperty, value); }
}WPF中的强制是这样做的:
private static object CoerceMinimum(DependencyObject source, object value)
{
Range r = source as Range;
double maximum = r.Maximum;
double val = (double)value;
if (val > maximum)
{
return maximum;
}
return value;
}PropertyChangedCallback看起来像这样:
private static void OnMinimumChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
Range r = source as Range;
r.CoerceValue(LowerValueProperty);
r.CoerceValue(UpperValueProperty);
r.CoerceValue(MaximumProperty);
}在这种情况下,ValidateValueCallback并不重要。其他回调类似于所示的代码。
在WPF中,这运行得很好。例如,我设置(在XAML中)
<Range LowerValue="12" Minimum="10" UpperValue="15" Maximum="20" />所有值都是正确的。顺序并不重要!
但在Silverlight中,我无法让它运行。
第一步是解决CoerceValueCallback的问题。我提高了PropertyChangedCallback中的强制,如下所示:
private static void OnMinimumChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
Range r = source as Range;
double newVal = (double)e.NewValue;
double coercedVal = (double)CoerceMinimum(source, newVal);
if (coercedVal != newVal)
{
r.Minimum = coercecVal;
return;
}
r.CoerceValue(LowerValueProperty);
r.CoerceValue(UpperValueProperty);
r.CoerceValue(MaximumProperty);
}如果现在将Minimum设置为某个值,则仍然执行CoerceMinimum,并且最小强制执行得很好。
但是最后三行不能编译,因为DependencyObject没有CoerceValue方法。而这正是我一筹莫展的位置。
如何在MinimumChanged上提高对LowerValue、UpperValue和Maximum的强制?或者,是否有其他方法可以确保初始化顺序无关紧要,并且所有属性都被正确设置(假设满足条件)?
提前感谢!
发布于 2011-07-04 18:33:29
我有一个解决方案:)我敢肯定,它还没有完成。我仍然需要调试所有可能的命令,但我想大部分已经完成了。
我只发布了LowerValue的代码,其他的几乎是一样的:
最小值和最大值的强制很简单。如果新值大于Maximum (或小于Minimum),则采用Maximum (或Minimum),否则采用新值。
代码如下:
private static void OnLowerValueChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
Range r = source as Range;
if (r._levelsFromRootCall == 0)
{
r._requestedLowerVal = (double)e.NewValue;
}
r._levelsFromRootCall++;
r.CoerceLowerValue();
r.CoerceUpperValue();
r._levelsFromRootCall--;
}
private void CoerceLowerValue()
{
double minimum = this.Minimum;
double maximum = this.Maximum;
double lowerVal = this.LowerValue;
double upperVal = this.UpperValue;
if (lowerVal != _requestedLowerVal && _requestedLowerVal >= minimum && _requestedLowerVal <= maximum)
{
if (_requestedLowerVal <= upperVal)
{
base.SetValue(LowerValueProperty, _requestedLowerVal);
}
else
{
base.SetValue(LowerValueProperty, upperVal);
}
}
else
{
if (lowerVal < minimum)
{
base.SetValue(LowerValueProperty, minimum);
}
else if (lowerVal > upperVal || _requestedLowerVal > upperVal)
{
base.SetValue(LowerValueProperty, upperVal);
}
else if (lowerVal > maximum)
{
base.SetValue(LowerValueProperty, maximum);
}
}
}https://stackoverflow.com/questions/6547836
复制相似问题