WCF/WF - Observable Collection - Asked By s j on 22-Feb-12 04:19 AM


Hi,

Can anybody explain about Observable Collection. I'm learning WPF where i have to use this to bind some data to the controls and display.


Cheers,
Samantha.
Somesh Yadav replied to s j on 22-Feb-12 04:30 AM
Hi,

ObservableCollection(Of T) can be used as a XAML object element in Windows Presentation Foundation (WPF), in versions 3.0 and 3.5. However, the usage has substantial limitations.

  • ObservableCollection(Of T) must be the root element, because the x:TypeArguments attribute that must be used to specify the constrained type of the generic ObservableCollection(Of T) is only supported on the object element for the root element.

  • You must declare an x:Class attribute (which entails that the build action for this XAML file must be Page or some other build action that compiles the XAML).

  • ObservableCollection(Of T) is in a namespace and assembly that are not initially mapped to the default XML namespace. You must map a prefix for the namespace and assembly, and then use that prefix on the object element tag for ObservableCollection(Of T).

A more straightforward way to use ObservableCollection(Of T) capabilities from XAML in an application is to declare your own non-generic custom collection class that derives from ObservableCollection(Of T), and constrains it to a specific type. Then map the assembly that contains this class, and reference it as an object element in your XAML.


Syntax:-

[SerializableAttribute]
public class ObservableCollection<T> : Collection<T>, 
	INotifyCollectionChanged, INotifyPropertyChanged


Example:-

This example shows how to create and bind to a collection that derives from the ObservableCollection(Of T) class, which is a collection class that provides notifications when items get added or removed.

The following example shows the implementation of a NameList collection:

public class NameList : ObservableCollection<PersonName>
{
    public NameList() : base()
    {
        Add(new PersonName("Willa", "Cather"));
        Add(new PersonName("Isak", "Dinesen"));
        Add(new PersonName("Victor", "Hugo"));
        Add(new PersonName("Jules", "Verne"));
    }
  }

  public class PersonName
  {
      private string firstName;
      private string lastName;

      public PersonName(string first, string last)
      {
          this.firstName = first;
          this.lastName = last;
      }

      public string FirstName
      {
          get { return firstName; }
          set { firstName = value; }
      }

      public string LastName
      {
          get { return lastName; }
          set { lastName = value; }
      }
  }


You can make the collection available for binding the same way you would with other common language runtime (CLR) objects, as described in How to: Make Data Available for Binding in XAML. For example, you can instantiate the collection in XAML and specify the collection as a resource, as shown here:

<Window
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:c="clr-namespace:SDKSample"
  x:Class="SDKSample.Window1"
  Width="400"
  Height="280"
  Title="MultiBinding Sample">
	
  <Window.Resources>
    <c:NameList x:Key="NameListData"/>


...


</Window.Resources>


You can then bind to the collection:

<ListBox Width="200"
         ItemsSource="{Binding Source={StaticResource NameListData}}"
         ItemTemplate="{StaticResource NameItemTemplate}"
         IsSynchronizedWithCurrentItem="True"/>

Hope it helps you.

Web Star replied to s j on 22-Feb-12 04:31 AM
Actually Observable collection are use for dynamic data representation which notify when add/edit/delete/refresh operation perform in WPF. Bascially the observable collection in wpf sync the control to data source at runtime.
For more details about this need to see these articles
http://msdn.microsoft.com/en-us/library/ms668604.aspx 
http://www.codeproject.com/Articles/47914/Working-with-ObservableCollection-T 
 hope this helps you
Suchit shah replied to s j on 22-Feb-12 04:38 AM
observable collection Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
One of the most useful classes when working with WPF can be found in the System.ComponentModel namespace, namely the ObservableCollection<T>. This class notifies interested parties of changes to its internal item collection.

Specifically concerning WPF, the ObservableCollection class allows you to bind ItemsControl derived classes, like so: <ListBox ItemsSource="{Binding Contacts}"/>. Assuming the DataContext of the Listbox has a property named Contacts (which has to be a collection type), the Listbox will populate the Listbox with ListboxItems for you. If the property is of type ObservableCollection, then the Listbox will automatically propagate changes into the UI.


Creating an ObservableCollection is pretty straight forward.

1. For example say we have class Customer { id, name, address }

2. Now lets create a DataSrc that returns an ObservableCollection of Customer
public class CustomerDataSrc
{
private ObservableCollection<Customer> _results = new
ObservableCollection<Customer>();
public ObservableCollection<Customer> Customers {get { return _results; }}
private void LoadCustomers()
{
IList<Customer> customers = YourDAL.FindAll();
foreach (Customer customer in customers)
{
_results.Add(customer);
}
}
}

3. Declare an ObjectDataProvider in your XAML Page.Resources
<Page.Resources>
<ObjectDataProvider x:Key="CustomerDataSrc"
d:IsDataSource="True"
ObjectType="{x:Type Client_DataSources:CustomerDataSrc}"/>
</Page.Resources>

4. Bind the ListView like this:
<ListView x:Name="dataGrid"
ItemsSource="{Binding Path=Customers,
Mode=Default,
Source={StaticResource CustomerDataSrc}}">

5. In the code behind do this: (change according to the on button click event)

private void Page_Loaded(object sender, RoutedEventArgs e)
{
ObjectDataProvider odp = this.FindResource("CustomerDataSrc") as ObjectDataProvider;
_customerSrc = odp.ObjectInstance as CustomerDataSrc;
_customerSrc.IsDesignTime = System.ComponentModel.DesignerProperties.GetIsInDesignMode(this);
_customerSrc.LoadCustomers();
}

s j replied to Web Star on 24-Feb-12 01:11 AM


Hi,
I have tried with your code but it is not working for me.
I got confused with binding and observable collections. Can u plz provide me some more info on this..


Cheers,
Samantha.