Reppien
Reppien

Reputation: 125

Basic Databinding in WPF

I'm currently writing a program for drawing class diagrams, and I'm using the MVVM pattern. My classes' width and height in the user interface is set to auto, as I let the containing elements define the size.

Problem is that I need the width and the height in my model to do some calculations, so I need a reverse binding or something to update the properties in my model, which I don't know much about. How do I do this?

I tried this, but didn't work:

XAML:

Width="{Binding Width, Mode=OneWayToSource}" Height="{Binding Height,
Mode=OneWayToSource}">

C#

private int width;
    public int Width {
        get { return width; }
        set {
            width = value;
        }
    }
    private int height;
    public int Height {
        get { return height; }
        set {
            height = value;
        }
    }

Upvotes: 1

Views: 235

Answers (4)

AJ.
AJ.

Reputation: 1671

What you have there should correctly update your width and height member variables when you resize whatever element the XAML is pointing to.

If you also want to update the values in code and have that reflected in your XAML element, you will need INotifyPropertyChanged and TwoWay binding. You could also use dependency properties, but you probably don't want to do that in ViewModel code.

Edit: Per my comment below, it appears that you wanted to bind to the ActualWidth and ActualHeight properties. MS Silverlight documentation states:

For purposes of ElementName binding, ActualWidth does not post updates when it changes (due to its asynchronous and run-time calculated nature). Do not attempt to use ActualWidth as a binding source for an ElementName binding. If you have a scenario that requires updates based on ActualWidth, use a SizeChanged handler.

The .NET Framework 4.5 documentation does not state the same caveat, but it seems to be implied for ReadOnly DP's. I have also seen workarounds for this online using Triggers in XAML. See the discussion following the accepted answer here. This discussion suggests that MS have no intention of fixing this issue with ReadOnly DP's.

Upvotes: 1

D J
D J

Reputation: 7018

You can try with

ActualWidth="{Binding Width, Mode=OneWayToSource}" ActualHeight="{Binding Height,
Mode=OneWayToSource}">

But this code may not work everytime as atual width and height are not available until UI is rendered.

Or you may create the dependency property in VM and bind it with width and height with Mode=OneWay. But your frame work should support this as you are using MVVM.

Upvotes: 0

Edited:

There are 3 things which you might have to do.

  1. Your class (model or view model where Width and Height properties are defined) needs to implement INotifyPropertyChanged interface.

  2. You also need two way binding, since you wanted to set Width/Height from code as well as capture it from the user.

  3. You need to bind with the ActualWidth and ActualHeight - What is the difference between Width and ActualWidth in WPF?

More info on INotifyPropertyChanged - http://msdn.microsoft.com/en-us/library/ms743695.aspx

Upvotes: 0

Big Daddy
Big Daddy

Reputation: 5234

Make sure that your view-model is set as the DataContext of your view. You'll need to implement INotifyPropertyChanged in your view-model. Then, update your properties to look like this:

    public int Width 
    {
        get { return width; }
        set 
          {
            if(width != value)
              {
                 width = value;
                 NotifyPropertyChanged();
              }
          }
    }

Upvotes: 0

Related Questions