Страницы

Поиск по вопросам

пятница, 1 марта 2019 г.

Свойство зависимости из UserControl в MainWindow

Не работает свойство зависимости
UserControl.cs:
// private double Radius = 100; private void DrawScale() { double bigTick = 9; for (double i = 0; i <= 90; i = i + bigTick) { Point p = new Point(0.5, 0.5); Rectangle r = new Rectangle { Height = 5, Width = 15, Fill = new SolidColorBrush(Colors.Aqua), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, RenderTransformOrigin = p };
TransformGroup trGp = new TransformGroup(); RotateTransform rTr = new RotateTransform(); double iRadian = (i * Math.PI) / 180; rTr.Angle = i; trGp.Children.Add(rTr); TranslateTransform tTr = new TranslateTransform(); tTr.X = (int) ((Radius) * Math.Cos(iRadian)); tTr.Y = (int) ((Radius) * Math.Sin(iRadian)); trGp.Children.Add(tTr); r.RenderTransform = trGp; gr.Children.Add(r); } }
public double Radius { get { return (double)GetValue(MyPropertyProperty); } set { SetValue(MyPropertyProperty, value); } }
public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register("Radius", typeof(double), typeof(RoundScale), null);
userControl.xaml

MainWindow.xaml

Если переменную Radius в UserControl.cs разкомментировать и удалить из кода свойство зависимости то все работает как надо.


Ответ

Вы неправильно определили dependency property. CLR-свойство должно называться так, как ваше dependency property, минус суффикс Property. В вашем случае dependency property называется MyPropertyProperty, а CLR-свойство — Radius
Переименуйте dependency property в RadiusProperty

Документация: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/custom-dependency-properties#checklist-for-defining-a-dependency-property
When you create the identifier field, name this field by the name of the property as you registered it, plus the suffix Property

Ещё одна проблема — опрос dependency property из конструктора. Дело в том, что значение dependency property, заданное непосредственно в XAML, устанавливается в InitializeComponent, а привязки могут сработать ещё позже. Поэтому имеет смысл либо читать значение на событии Loaded, либо подписаться на изменения.

Если вам нужно подписаться на изменения, проще всего указать callback в определении dependency property:
public double Radius { get { return (double)GetValue(RadiusProperty); } set { SetValue(RadiusProperty, value); } }
public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register( "Radius", typeof(double), typeof(RoundScale), new PropertyMetadata(0.0, OnRadiusChangedStatic));
static void OnRadiusChangedStatic(DependencyObject d, DependencyPropertyChangedEventArgs e) => ((RoundScale)d).OnRadiusChanged();
void OnRadiusChanged() { // тут у вас поменялся радиус, реагируйте }

Комментариев нет:

Отправить комментарий