Congratulations to all the winners of April 2013, they have won INR 3400 cash and INR 20147 worth prizes !
Go to DotNetFunda.com
Twitter TwitterLinkedIn
YouTubeGoogle
 Online : 16584 |  Welcome, Guest!   Register  Login
Home > Articles > WPF > WPF Tutorial : Concept Binding 6

WPF Tutorial : Concept Binding 6

1 vote(s)
Rating: 5 out of 5
Article posted by Abhi2434 on 8/15/2010 | Views: 38713 | Category: WPF | Level: Beginner | Points: 300 red flag


Binding is the most important topic of WPF programming. In this article I have demonstrated how you could employ DataBinding to ensure that the Presentation logic is separated from the View and also give simple demonstration on how the DataBinding concept works. The article also gives you the basics of CommandBinding and MultiBinding.

Download


 Download source code for WPF Tutorial : Concept Binding 6


Introduction


Before this article, I have discussed about the architecture of WPF, Markup extensions, dependency properties, logical trees and Visual trees, layout, transformation etc. Today I will discuss what we call the most important part of any WPF application, the binding. WPF comes with superior DataBinding capabilities which enables the user to bind objects so that whenever the other object changes, the main object reflects its changes. The main motive of DataBinding is to ensure that the UI is always synchronized with the internal object structure automatically.

Before going further, lets jot down on the things that we have already discussed. If you are new to this article, you can start from my other articles in the list below:



DataBinding was present before introduction of WPF. In ASP.NET we bind data elements to render proper data from the control. We generally pass in a DataTable and bind the Templates to get data from individual DataRows. On the other hand, in case of traditional windows forms application, we can also bind a property with a data element. The Bindings can be added to properties of objects to ensure whenever the property changes the value, the data is internally reflected to the data. So in one word, DataBinding is nothing new to the system. The main objective of DataBinding is to show data to the application and hence reducing the amount of work the application developer needs to write to just make the application properly display data. In this article, I will discuss how you could use the Databinding in WPF application and also create a sample application to demonstrate the feature in depth.



Binding in WPF


WPF puts the concept of Binding further and introduced new features, so that we could use the Binding feature extensively. Binding establishes the connection between the application and the business layers. If you want your application to follow strict design patter rules, DataBinding concept will help you to achieve that. We will look into greater detail with how to do that in a while.

In WPF we can bind two Properties, One Property and one DependencyProperty, two DependencyProperties etc. WPF also supports Command Binding. Lets discuss how to implement them in detail.

Binding can be classified into few Types :

DataBinding / Object Binding


The most important and primary binding is Databinding. WPF introduces objects like ObjectDataProvider and XMLDataProvider to be declared into XAML to enhance the capability of object binding. DataBinding can be achieved by several ways. As shown by Adnan in his blog we can make use of Binding capabilities by employing either XAML, XAML and C#, and C# itself. So WPF is flexible enough to handle any situation.



<TextBox x:Name="txtName" />
<TextBlock Text="{Binding ElementName=txtName, Path=Text.Length}" />
In the above situation, I have shown the most basic usage of Binding. The Text property of TextBlock is bound with the TextBox txtName so that whenever you enter something on the TextBox during runtime, the TextBlock will show the length of the string.

As a Markup Extension binding is actually a Class with properties. Here we specified the value of the property ElementName and Path. The ElementName ensures that the object that the property belongs to. Path determines the property path which the object needs to look into.

You can use ObjectDataProvider to handle data in your XAML easily. ObjectDataProvider can be added as Resource and later on can be referenced using StaticResource. Lets see the code below :

  <StackPanel Orientation="Vertical">
    <StackPanel.Resources>
      <ObjectDataProvider ObjectType="{x:Type m:StringData}" x:Key="objStrings" MethodName="GetStrings"/>
    </StackPanel.Resources>
    <ListBox Name="lstStrings" Width="200" Height="300" ItemsSource="{Binding Source={StaticResource objStrings}}" />

Just as shown above the ObjectType will get a Type, which is the internal class structure for which the Method GetStrings will be called for. From the ListBox, I have referenced the Object using StaticResource.

Now in the code you can declare a class

 public class StringData
{
ObservableCollection<String> lst= new ObservableCollection<String>();

public StringData()
{
lst.Add("Abhishek");
lst.Add("Abhijit");
lst.Add("Kunal");
lst.Add("Sheo");
}
public ObservableCollection<String> GetStrings()
{
return lst;
}
}

So you can see the list been populated with the strings.

Why ObservableCollection , the INotifyPropertyChanged, INotifyCollectionChanged?

Now as you can see I have used ObvervableCollection. This is important. ObservableCollection sends automatic notification when a new item is inserted. Thus notifies the ListBox to update the list. So if you place a button,which inserts some data in the ObservableCollection, the Binding will automatically be notified by the collection  and hence update the collection automatically. You dont need to manually insert the same in the ListBox.

WPF Binding generally needs to be notified when it is modified. The interfaces INotifyPropertyChanged and INotifyCollectionChanged are needed to update the UIElement which is bound with the data. So if you are crating a property which needed to update the UI when the value of it is modified, the minimum requirement is to implement the same from INotifyPropertyChanged, and for collection (like ItemsSource), it needs to implement INotifyCollectionChanged. ObservableCollection itself implements INotifyCollectionChanged, so it has support to update the control whenever new item is inserted to the list or any old item is removed from the string.

I have already discussed the two in detail in an article :
Change Notification for Objects and Collection

XML Binding


Similar to Object binding, XAML also supports XML binding. You can bind the data coming from XMLDataProvider easily using built in properties like XPath in Binding class definition. Lets look into the code :

<TextBlock Text="{Binding XPath=@description}"/>
<TextBlock Text="{Binding XPath=text()}"/>
So if you are in the node XYZ, the InnerText can be fetched using text() property. The @ sign is used for Attributes. So using XPath you can easily handle your XML.

If you want to read more about XML binding check:
XML Binding in WPF

Importance of DataContext


You might wonder why I have took context of DataContext while I am talking about WPF Bindings. DataContext is actually a Dependency property. It points to Raw Data such that the object that we pass as DataContext will inherit to all its child controls. I mean to say if you define the DataContext for a Grid, then all the elements that are inside the Grid will get the same DataContext.

<Grid DataContext="{StaticResource dtItem}">
<TextBox Text="{Binding MyProperty}" />
</Grid>
Here as I defined DataContext for the Grid, the TextBox inside the grid can refer to the property MyProperty as the dtItem object will be automatically inherited to all its child elements. While using Binding, DataContext is the most important part which you must use.

Binding Members


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, ElementName 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 ToString 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. TwoWay 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 IValueConverter 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 :

Download Sample Application - 265KB

Conclusion


I think you must be enjoying the series.  If you want to complete list of the series, please visit
WPF Learning Series

Also feel free to write your comments. Thanks for reading.

If you like this article, subscribe to our RSS Feed. You can also subscribe via email to our Interview Questions, Codes and Forums section.

Page copy protected against web site content infringement by Copyscape
Found interesting? Add this to:



Please Sign In to vote for this post.

About Abhishek Sur

Experience:3 year(s)
Home page:http://www.abhisheksur.com
Member since:Wednesday, December 02, 2009
Level:Silver
Status: [Member] [Microsoft_MVP] [MVP]
Biography:Working for last 2 and 1/2 years in .NET environment with profound knowledge on basics of most of the topics on it.
 Responses
Posted by: Ganeshji | Posted on: 19 Aug 2010 01:25:25 PM | Points: 10

hm! it is nice. But the drawings are excellent. Drawing korlen?

>> Write Response - Respond to this post and get points
Related Posts

We will see how we can pass parameters to a WPF Click-Once Application and depends on the parameter we can use the application.

This article shows how to provide a rich user experience by providing a perfect tool tip.

This is an Application which can change your default Logon Screen of Windows XP. There are many applications that allow you to do this Application’s like Logon Studio etc. I have developed this simple application in WPF using Vb.Net. You can see how i made it by following the description below. The Application does Not use any DLL’s nor does it use any API so it is very easy to understand.

WPF added lot of flexibility and usability to the client application development. There are lots of features in WPF for enhancing the usability aspects of a client application. One of the interesting and very useful features is the WPF adorner. In this article we will discuss briefly about Adorner and how to create a simple adorner.

In this article I have showed how you can build pluggable Resources for styles, Languages or any static objects etc. Therefore building a new style doesn't hampers your code and you can easily plugin any new style to the application inspite it is already in production environment. I have added a language converter tool, which will generate multi lingual resources for you.

More ...
About Us | Contact Us | The Team | Advertise | Software Development | Write for us | Testimonials | Privacy Policy | Terms of Use | Link Exchange | Members | Go Top
General Notice: If you find plagiarised (copied) contents on this page, please let us know the original source along with your correct email id (to communicate) for further action.
Copyright © DotNetFunda.Com. All Rights Reserved. Copying or mimicking the site design and layout is prohibited. Logos, company names used here if any are only for reference purposes and they may be respective owner's right or trademarks. | 5/19/2013 5:47:05 AM