Решил проверить порядок вызова Callback'ов для DependencyProperty следующим кодом:
public class CustomControl : UserControl
{
public static readonly DependencyProperty CustomPropertyProperty;
public static event EventHandler PropertyChangedCallbackIsRised;
public static event EventHandler CoerceValueCallbackIsRised;
public static event EventHandler ValidateValueCallbackIsRised;
static CustomControl()
{
var metadata = new FrameworkPropertyMetadata(
10, CustomPropertyChangedValuCallback, CustomPropertyCoerceValueCallback);
CustomPropertyProperty = DependencyProperty.Register(
"MyProperty", typeof(int), typeof(CustomControl), metadata, CustomPropertyValidateValueCallback);
}
private static void CustomPropertyChangedValuCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
PropertyChangedCallbackIsRised?.Invoke(null, null);
}
private static object CustomPropertyCoerceValueCallback(DependencyObject d, object baseValue)
{
CoerceValueCallbackIsRised?.Invoke(null, null);
return baseValue;
}
private static bool CustomPropertyValidateValueCallback(object value)
{
ValidateValueCallbackIsRised?.Invoke(null, null);
return true;
}
public int CustomProperty
{
get { return (int)GetValue(CustomPropertyProperty); }
set { SetValue(CustomPropertyProperty, value); }
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
CustomControl.PropertyChangedCallbackIsRised += CustomControl_PropertyChangedCallbackIsRised;
CustomControl.CoerceValueCallbackIsRised += CustomControl_CoerceValueCallbackIsRised;
CustomControl.ValidateValueCallbackIsRised += CustomControl_ValidateValueCallbackIsRised;
// В XAML разметке есть TextBox txtInfo в который выводится инфа
var customControl = new CustomControl();
txtInfo.Text = "Deafult value : " + customControl.CustomProperty + "\r\n";
customControl.CustomProperty = 100;
txtInfo.Text += "New value1 : " + customControl.CustomProperty + "\r\n";
customControl.CustomProperty = 1000;
txtInfo.Text += "New value2 : " + customControl.CustomProperty;
}
private void CustomControl_ValidateValueCallbackIsRised(object sender, EventArgs e)
{
txtInfo.Text += "ValidateValueCallback\r\n";
}
private void CustomControl_CoerceValueCallbackIsRised(object sender, EventArgs e)
{
txtInfo.Text += "CoerceValueCallback\r\n";
}
private void CustomControl_PropertyChangedCallbackIsRised(object sender, EventArgs e)
{
txtInfo.Text += "PropertyChangedCallback\r\n";
}
}
Получил вывод:
Deafult value : 10
ValidateValueCallback
CoerceValueCallback
PropertyChangedCallback
New value1 : 100
ValidateValueCallback
CoerceValueCallback
PropertyChangedCallback
New value2 : 1000
При этом в книге "Pro WPF 4.5 in С#" Matthew MacDonald'а утверждается, что порядок должен быть таким:
CoerceValueCallback
ValidateValueCallback
PropertyChangedCallback
Отсюда два вопроса:
1) Почему между значениями 10 и 100 ValidateValueCallback вылетает два раза?
2) Почему между значениями 100 и 1000 порядок другой?