# 相依性屬性回呼和驗證Dependency Property Callbacks and Validation

## 驗證回撥Validation Callbacks

public static readonly DependencyProperty CurrentReadingProperty = DependencyProperty.Register(
typeof(double),
typeof(Gauge),
Double.NaN,
),
);
{
}

Public Shared ReadOnly CurrentReadingProperty As DependencyProperty =
GetType(Double), GetType(Gauge),

Get
End Get
Set(ByVal value As Double)
End Set
End Property


public static bool IsValidReading(object value)
{
Double v = (Double)value;
return (!v.Equals(Double.NegativeInfinity) && !v.Equals(Double.PositiveInfinity));
}

Public Shared Function IsValidReading(ByVal value As Object) As Boolean
Dim v As Double = CType(value, Double)
Return ((Not v.Equals(Double.NegativeInfinity)) AndAlso
(Not v.Equals(Double.PositiveInfinity)))
End Function


## 強制轉型值回撥和屬性變更事件Coerce Value Callbacks and Property Changed Events

public static readonly DependencyProperty CurrentReadingProperty = DependencyProperty.Register(
typeof(double),
typeof(Gauge),
Double.NaN,
),
);
{
}

Public Shared ReadOnly CurrentReadingProperty As DependencyProperty =
GetType(Double), GetType(Gauge),

Get
End Get
Set(ByVal value As Double)
End Set
End Property


private static void OnCurrentReadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}

Private Shared Sub OnCurrentReadingChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
End Sub


private static object CoerceCurrentReading(DependencyObject d, object value)
{
Gauge g = (Gauge)d;
double current = (double)value;
return current;
}

Private Shared Function CoerceCurrentReading(ByVal d As DependencyObject, ByVal value As Object) As Object
Dim g As Gauge = CType(d, Gauge)
Dim current As Double = CDbl(value)
End If
End If
Return current
End Function


## 進階的強制型轉和回撥案例Advanced Coercion and Callback Scenarios

### 條件約束和所需的值Constraints and Desired Values

CoerceValueCallback屬性系統強制值符合您宣告時，邏輯，但強制轉型的本機設定值使用回撥屬性仍然會保留 「 所需的值 」 在內部。The CoerceValueCallback callbacks will be used by the property system to coerce a value in accordance to the logic you declare, but a coerced value of a locally set property will still retain a "desired value" internally. 如果條件約束是以在應用程式存留期間可能動態變更的其他屬性值為基礎，則強制型轉條件約束也會動態變更，而受條件約束的屬性可以變更其值，以儘量接近新條件約束指定的所需值。If the constraints are based on other property values that may change dynamically during the application lifetime, the coercion constraints are changed dynamically also, and the constrained property can change its value to get as close to the desired value as possible given the new constraints. 如果提取所有條件約束，則值會成為所需的值。The value will become the desired value if all constraints are lifted. 如有多個屬性彼此循環相依，您可能會造成相當複雜的相依性情況。You can potentially introduce some fairly complicated dependency scenarios if you have multiple properties that are dependent on one another in a circular manner. 例如，在最小值/最大值/目前值的案例中，您可以選擇讓使用者能設定最小值和最大值。For instance, in the Min/Max/Current scenario, you could choose to have Minimum and Maximum be user settable. 如果這樣，您可能需要強制轉型「最大值」一律大於「最小值」，反之亦然。If so, you might need to coerce that Maximum is always greater than Minimum and vice versa. 但若該強制型轉為作用中，且「最大值」強制轉型成「最小值」，會讓目前值處於無法設定的狀態，因為它相依於兩者，且受條件約束在值的範圍內，也就是零。But if that coercion is active, and Maximum coerces to Minimum, it leaves Current in an unsettable state, because it is dependent on both and is constrained to the range between the values, which is zero. 然後，如果調整「最大值」或「最小值」，目前值就似乎會「遵循」其中一個值，因為因為當條件約束放寬時，目前值的所需值仍會儲存並嘗試達到所需的值。Then, if Maximum or Minimum are adjusted, Current will seem to "follow" one of the values, because the desired value of Current is still stored and is attempting to reach the desired value as the constraints are loosened.