19 January, 2011

WP7: How to create binding programmatically

If you ever find yourself creating dynamic pages in a Silverlight project (WP7-project) and at the same time using the MVVM-model, you are sometimes presented with the need of creating a binding at runtime.

I have an application on the way that utilizes a dynamic “property editor page” in the same way as the native Contact editor of the WP7-phone. This property editor page can take a number of different property types (string, int, double, datetime) and I want the editor page to display the correct property editor control (textbox, datetime picker etc.). See the sequence below (parent page, texteditor, datetime picker).

image image image

Now – all these controls are present on the property editor page, but only the relevant editor control should be visible. The visibility property is handled by a custom IValueConverter implementation (see other post), but this post is about hooking up the editor control dynamically.

In the UI logic of the property editor page, the OnNavigatedTo method is overwritten and responsible for initializing the ViewModel (VM) by the call to vm.InitializeCmd.Execute(null). This will allow the VM to determine which controltype should be visible (method=InitView).

ViewModel:
private void InitView()
{
var pI = IsolatedStorageSettings.ApplicationSettings[Constants.CURRENT_PROPERTY] as PropertyInfo;
if (pI == null) throw new ArgumentNullException();
PropInfo = pI;

//what control to enable?
TextBoxVisible = (pI.PropertyType == typeof (string));
DatePickerVisible = (pI.PropertyType == typeof (DateTime));

//final binding logic is found in UI (propertyview.xaml.cs).
}



View logic:

The next thing is in the UI-logic (i.e. propertyview.xaml.cs). Here OnNavigatedTo is overwritten to first call ViewModel.InitializeCmd and next create the binding I require.

        protected override void OnNavigatedTo(NavigationEventArgs e)
{
var vm = (PropertyViewModel)DataContext;
vm.InitializeCmd.Execute(null);

//set binding (textbox)
if(vm.TextBoxVisible)
{
var b = new Binding("Text") { Source = vm.PropInfo.PropertyValue, Mode = BindingMode.TwoWay };
txtValue.SetBinding(TextBox.TextProperty, b);
}

//..rest omited


By using this method, the binding is made at runtime and you can bind to any control matching your need.


Technorati Tags: ,

No comments: