I'm currently doing some rescaling on data in a valueconverter whenever a panel is redrawn. I want to move some of this processing to the viewmodel as the most of the processing only occurs if the control size or a few other properties change.
To ensure the rescaled data looks acceptable I need the ActualWidth
of the container in the viewmodel. I want to bind it to a property of the viewmodel one way so when it changes I can trigger the rescaling processing.
All the examples I could find bind a CLR or dependency property to an element rather than the other way and I'm clearly missing something in my understanding to work out how I should do it. I have have tried a few different things setting up the binding but am just not getting it right.
Any hints? thanks.
In MyView XAML:
<myItemsControl/>
In MyView code behind, something like:
Binding b = new Binding(MyWidthProperty);
b.Mode = BindingMode.OneWay;
b.Source = myItemsControl.Name;
.........?
and
public static readonly DependencyProperty MyWidthProperty =
DependencyProperty.Register( "MyWidth", typeof(Double), typeof(MyViewModel));
In MyViewModel:
public Double MyWidth{
get { return _myWidth; }
set { _myWidth = value; ViewChanged(this); } }
You cannot do it this way. You cannot set a Binding
to ActualWidth
, as it's read-only.
You can only set a binding to MyWidth
. But for this, you need first to convert MyWidth into a DependencyProperty
. Then you will be able to do something like
Binding b = new Binding("ActualWidth") { Source = myItemsControl };
this.SetBinding(MyViewModel.MyWidthProperty, b);
For converting into a dependency property, you'll need to replace your definition of MyWidth
with the following:
public static readonly DependencyProperty MyWidthProperty =
DependencyProperty.Register("MyWidth", typeof(double), typeof(MyViewModel),
new UIPropertyMetadata(
0.0,
(d, e) =>
{
var self = (MyViewModel)d;
ViewChanged(self);
}));
But be careful with dependency properties; it's better to read the documentation first.
Edit: You would also need to define the property this way:
public double MyWidth
{
get { return (double)this.GetValue(MyWidthProperty); }
set { this.SetValue(MyWidthProperty, value); }
}