Saturday, 11 May 2013

Binding Members | WPF Tutorial pdf

As you all know about Markup Extensions, Binding is actually a Markup Extension. It is a class Binding with few properties. Lets discuss about the Members that are there in Binding :
1. Source : The source property holds the DataSource. By default it reference the DataContext of the control. If you place Source property for the Binding, it will take that in liew of original DataContext element.
2. ElementName : In case of Binding with another Element, Element Name takes the name of the Element defined within the XAML for reference of the object.
ElementName acts as a replacement to Source. If path is not specified for the Binding, it will use ToString to get the data from the Object passed as Source.
3. Path : Path defines the actual property path to get the String Data. If the end product is not a string, it will also invoke To String to get the data.
4. Mode : It defines how the Data will be flown. OneWay means object will be updated only when source is updated, on the contrary OneWayToSource is the reverse. Two Way defines the data to be flown in both ways.
5. UpdateSourceTrigger : This is another important part of any Binding. It defines when the source will be updated. The value of UpdateSourceTrigger can be :
=> PropertyChanged : It is the default value. As a result whenever the anything is updated in the control, the other bound element will reflect
the same.
=> LostFocus : It means whenever the property loses its focus, the property gets updated.
=> Explicit : If you choose this option, you need to explicitly set when to update the Source. You need to use UpdateSource of BindingExpression to update the control.
BindingExpression bexp = mytextbox.GetBindingExpression(TextBox.TextProperty);
bexp.UpdateSource();

By this the source gets updated.
6. Converter : Converter gives you an interface to put an object which will be invoked whenever the Binding objects gets updated. Any object that implements IValue Converter can be used in place of Converter.
You can read more about it from :
Converter in DataBinding
7. ConverterParameter : It is used in addition to Converter to send parameters to Converter.
8. FallbackValue : Defines the value which will be placed whenever the Binding cannot return any value. By default it is blank.
9. StringFormat : A formatting string that indicates the Format to which the data will follow.
10.ValidatesOnDataErrors : When specified, the DataErrors will be validated.
You can use IDataErrorInfo to run your custom Validation block when Data object is updated. You can read more about IDataErrorInfo from :Validate your application using IDataErrorInfo Using Code Similar to what you might do with XAML, you can also define binding in the codeBehind. To do this you need to use
Binding myBinding = new Binding("DataObject");
myBinding.Source = myDataObject;
myTextBlock.SetBinding(TextBlock.TextProperty, myBinding);

You can also specify the Binding properties in this way.

Command Binding
WPF Supports CommandBinding. Each command object like Button exposes a property called Command which takes an object that implements ICommand interface and will execute the method Execute whenever object command gets fired.
Say you want your command to be executed whenever the window Inputs gets invoked :
<Window.InputBindings>
<KeyBinding Command="{Binding CreateNewStudent}" Key="N"
Modifiers="Ctrl" />
<MouseBinding Command="{Binding CreateNewStudent}"
MouseAction="LeftDoubleClick" />
</Window.InputBindings>

In the above code, the CreateNewStudent is a property that exposes the object which inherits ICommand interface and the Execute method will be invoked whenever the Key Ctrl + N or LeftDoubleClick of the window is invoked.
Note : In VS 2008 the InputBindings only take Static Command objects. There is a bug report for this, and it will be fixed in later releases.
You can use CommandParameter to pass parameters to the methods that makes up the ICommand interface.
<Button Content="CreateNew" Command="{Binding CreateNewStudent}" />
Similar to InputBindings, you can use the Command with a Button. To Execute you need to create an object that implements ICommand like below :
public class CommandBase : ICommand
{
private Func<object, bool> _canExecute;
private Action<object> _executeAction;
private bool canExecuteCache;
public CommandBase(Action<object> executeAction, Func<object, bool>
canExecute)
{
this._executeAction = executeAction;
this._canExecute = canExecute;
}
#region ICommand Members
public bool CanExecute(object parameter)
{
bool tempCanExecute = _canExecute(parameter);
canExecuteCache = tempCanExecute;
return canExecuteCache;
}
private event EventHandler _canExecuteChanged;
public event EventHandler CanExecuteChanged
{
add { this._canExecuteChanged += value; }
remove { this._canExecuteChanged -= value; }
}
protected virtual void OnCanExecuteChanged()
{
if (this._canExecuteChanged != null)
this._canExecuteChanged(this, EventArgs.Empty);
}
public void Execute(object parameter)
{
_executeAction(parameter);
}
#endregion
}

I have used a CommandBase class to make the objects look less clumsy. The actual object class looks like :
private CommandBase createNewstudent;
public CommandBase CreateNewStudent
{
get
{
this.createNewstudent = this.createNewstudent ?? new
CommandBase(param => this.CreateStudent(), param => this.CanCreateStudent);
return this.createNewstudent;
}
}
private object CreateStudent()
{
this.CurrentStudent = new StudentItem();
return this.CurrentStudent;
}
public bool CanCreateStudent
{
get { return true; }
}

Thus you can see the createNewCommand passes CreateStudent lamda expression which is called whenever the object gets updated. The CanCreateStudent is a property that will also be called and based on True or false WPF will allow the command to execute.
The PropertyBinding and CommandBinding gives a total package to separate the presentation logic from the Presentaion Layer. This gives the architecture to put all the logic separated. Microsoft created the whole Expression blend using MVVM pattern which separates the View with the ViewModel and hence gives a chance to handle Unit Testing easily even for presentation layer. We will discuss more about the topic later on the Series.

MultiBinding
Similar to single Binding, WPF also introduces the concept of MultiBinding. In case of MultiBinding the data bound depends on more than one source. You can specify more than one binding expression and on each of them the actual output is dependent on.
<TextBlock DockPanel.Dock="Top" >
<TextBlock.Text>
<MultiBinding Converter="{StaticResource mbindingconv}">
<Binding ElementName="lst" Path="Items.Count" />
<Binding ElementName="txtName" Path="Text" />
<Binding ElementName="txtAge" Path="Text" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>

Here the value for TextBlock is dependent on 3 Elements, the first one is the ListBox count, then txtName and txtAge. I have used Converter to ensure we find all the individual element in the IMultiValueConverter block and handle each values separately. The IMultiValueConverter just similar to IValueConverter can take the value and return the object that are bound to the Text property.
public class MyMultiBindingConverter : IMultiValueConverter
{
#region IMultiValueConverter Members
public object Convert(object[] values, Type targetType, object
parameter, System.Globalization.CultureInfo culture)
{
string returnval = "Total no of Data {0}, NewData : ";
if (values.Count() <= 0) return string.Empty;
returnval = string.Format(returnval, values[0]);
for (int i = 1; i < values.Count(); i++)
returnval += "- " + values[i];
return returnval;
}
public object[] ConvertBack(object value, Type[] targetTypes, object
parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}

For simplicity I have just concat each values that are passed and returned back the output.
Sample Application In the sample application, I have produced the most simple Binding to ensure everything comes from the Model. You can find the sample application.

No comments: