views:

225

answers:

3

In WPF and Silverlight you can make a view model object and set it into the DataContext of a control when the control is constructed at runtime. You can then bind properties of the visual object to properties in your DataContext.

One way to set the binding is to type the binding directly into the tag:

<TextBox Text="{Binding Path=Description}"/>

And this will bind the textbox to the Description property in the view model.

The problem with typing in the binding is that you may make a typing mistake. (And you will almost certainly make a mistake if you have hundreds of bindings to make.)

In Expression Blend there is a little white dot beside the Text property in the Properties window. This brings up a menu from which you can Create Data Binding.

  • How can I get my view model properties to show in the Create Data Binding dialog so that I can select them.
  • Will the configuration of data binding in Blend interfere with setting my view model into the DataContext at runtime?
+1  A: 

One technique is to include the VM as a resource in your view:

<UserControl>
    <UserControl.Resources>
        <local:YourViewModel x:Key="ViewModel"/>
    </UserControl.Resources>
</UserControl>

You can then reference that as DataContext="{StaticResource ViewModel}" elsewhere.

Can't say I like it, but I can't say I like any of the view-first idiosynchrasies that Blend imposes on your design.

HTH, Kent

Kent Boogaart
I suppose you could set it up like this for design time setting up the bindings and if it causes a problem, comment it out for the build.
Doug Ferguson
The newer Blends support Design Time only bindings using a different namespace. See: http://stackoverflow.com/questions/1367684/are-expression-blend-design-time-specific-visuals-possible
sixlettervariables
+1  A: 

I experimented with Blend to find the drag and drop approach to data binding which still lets you override your view model in code easily.

  • First make your view model object which implements INotifyPropertyChanged and raises the notify event in the setters. The view models can be hierarchical. For example you could have an ObservableCollection within your main view model.
  • In Blend open up your page or control and go to the data tab.
  • On the right open the menu under the "Add live data source" icon.
  • Pick "Define new object data source"
  • Select your top level view model class and confirm the dialog

In my experiments I found that it was important to bind the data source to where I wanted it first or else Blend might make a less than optimal configuration if I didn't do the next step first.

  • Open the Objects and Timeline window in Blend
  • Select the root object, for example UserControl
  • Open Properties and verify that the root object is selected
  • Find DataContext and click the square to open the menu and select DataBinding
  • Select the data source that was just previously created

Now that the data source has been created data binding is very easy.

  • put some controls on the page
  • open the Data window
  • from the DataSource for your view model drag properties onto the controls to create the bindings or set the binding from the Properties window.

Now you can create you live view model object in the constructor of the control

public MainPage()
 {
  // Required to initialize variables
  InitializeComponent();
        mVm = new MyViewModel();
        this.DataContext = mVm;
 }
    private MyViewModel mVm;

Add any initialization to retrieve data and you are ready to go.

Doug Ferguson
+1  A: 

I have a screen cast on my blog Blendable MVVM : Introduction and Databinding which shows setting this up for Siverlight.

Essentially you create the ViewModel as the DataContext of the UserControl using the "New Object Initialiser" and then using the "Explicit Data Context" tab of the Binding dialog for the controls themselves.

Hope this helps.

Nigel Sampson
Your blog also has the answer to the next question I was wondering about; "How do you make a Blendable command?"
Doug Ferguson