2010-11-15 6 views
1

В настоящее время я делаю некоторое масштабирование данных в valueconverter всякий раз, когда панель перерисовывается. Я хочу переместить часть этой обработки в viewmodel, так как большая часть обработки возникает только при изменении размера элемента управления или нескольких других свойств.WPF: привязка к свойству readonly в коде

Чтобы убедиться, что данные с масштабированием выглядят приемлемыми, мне нужен контейнер ActualWidth в модели viewmodel. Я хочу привязать его к свойству viewmodel одним способом, поэтому, когда он изменится, я могу вызвать обработку перемасштабирования.

Все примеры, которые я смог найти, связывают свойство CLR или зависимостей с элементом, а не с другим, и я явно пропущу что-то в своем понимании, чтобы понять, как я должен это делать. Я попробовал несколько разных вещей, настраивая привязку, но просто не понимаю.

Любые подсказки? Благодарю.

В MyView XAML:

<myItemsControl/> 

В MyView коде позади, что-то вроде:

Binding b = new Binding(MyWidthProperty); 
b.Mode = BindingMode.OneWay; 
b.Source = myItemsControl.Name; 
.........? 

и

public static readonly DependencyProperty MyWidthProperty = 
DependencyProperty.Register("MyWidth", typeof(Double), typeof(MyViewModel)); 

В MyViewModel:

public Double MyWidth{ 
     get { return _myWidth; } 
     set { _myWidth = value; ViewChanged(this); } } 
+0

Я бы читать немного больше о DependencyProperty. В частности, ваш объект должен быть DependencyObject, и вы должны использовать методы GetValue и SetValue для доступа к базовому значению. Наконец, вы не получите вызов сеттера, когда DP получает доступ к системе привязки (это легко пропустить), поэтому вам нужно передать обработчик Changed в качестве части вызова Register. –

ответ

2

Вы не можете сделать это таким образом. Вы не можете установить Binding в ActualWidth, так как он доступен только для чтения.

Вы можете установить привязку только на MyWidth. Но для этого вам нужно сначала преобразовать MyWidth в DependencyProperty. Тогда вы будете в состоянии сделать что-то вроде

Binding b = new Binding("ActualWidth") { Source = myItemsControl }; 
this.SetBinding(MyViewModel.MyWidthProperty, b); 

Для преобразования в свойство зависимостей, вам нужно заменить ваше определение MyWidth следующим:

public static readonly DependencyProperty MyWidthProperty = 
    DependencyProperty.Register("MyWidth", typeof(double), typeof(MyViewModel), 
             new UIPropertyMetadata(
              0.0, 
              (d, e) => 
              { 
               var self = (MyViewModel)d; 
               ViewChanged(self); 
              })); 

Но будьте осторожны с свойством зависимостей ; лучше сначала прочитать документацию.

Edit: Кроме того, необходимо будет определить свойство так:

public double MyWidth 
{ 
    get { return (double)this.GetValue(MyWidthProperty); } 
    set { this.SetValue(MyWidthProperty, value); } 
} 
+0

Спасибо за этот очень полный ответ. Избегайте свойств зависимостей из-за неприятного синтаксиса, пока я добился прогресса в остальной части WPF. Первый раз, когда я был вынужден использовать один ... похоже, мне лучше подойдет к ним, поскольку я ожидаю, что это произойдет снова. – rjw

Смежные вопросы